From 6822ee353765366707ee0c00dae54b96658fd592 Mon Sep 17 00:00:00 2001 From: Sandertv Date: Thu, 9 Jan 2025 20:29:42 +0100 Subject: [PATCH] world/entity.go: EntityData: Embed tx and entity into data to avoid having to pass them everytime. --- server/entity/ent.go | 6 ++-- server/entity/firework_behaviour.go | 6 ++-- server/entity/passive.go | 6 ++-- server/entity/projectile.go | 6 ++-- server/player/player.go | 12 +++---- server/world/entity.go | 52 ++++++++++++++++------------- server/world/world.go | 2 +- 7 files changed, 47 insertions(+), 43 deletions(-) diff --git a/server/entity/ent.go b/server/entity/ent.go index d6ed48022..13e1ff3cf 100644 --- a/server/entity/ent.go +++ b/server/entity/ent.go @@ -63,7 +63,7 @@ func (e *Ent) Velocity() mgl64.Vec3 { // SetVelocity sets the velocity of the entity. The values in the Vec3 passed represent the speed on // that axis in blocks/tick. func (e *Ent) SetVelocity(v mgl64.Vec3) { - e.data.SetVelocity(e, e.tx, v) + e.data.SetVelocity(v) } // Rotation returns the rotation of the entity. @@ -126,8 +126,8 @@ func (e *Ent) Tick(tx *world.Tx, current int64) { e.SetOnFire(e.OnFireDuration() - time.Second/20) if m := e.Behaviour().Tick(e, tx); m != nil { - e.data.Move(e, tx, m.pos, m.rot, m.onGround) - e.data.SetVelocity(e, tx, m.vel) + e.data.Move(m.pos, m.rot, m.onGround) + e.data.SetVelocity(m.vel) } e.data.Age += time.Second / 20 } diff --git a/server/entity/firework_behaviour.go b/server/entity/firework_behaviour.go index 3a556acc8..e8b12276d 100644 --- a/server/entity/firework_behaviour.go +++ b/server/entity/firework_behaviour.go @@ -91,10 +91,10 @@ func (f *FireworkBehaviour) tick(e *Ent, tx *world.Tx) { // The client will propel itself to match the firework's velocity since // we set the appropriate metadata. - e.data.Move(e, tx, owner.Position(), e.data.Rotation(), false) - e.data.SetVelocity(e, tx, vel.Add(ownerVel.Add(dV.Mul(0.1).Add(dV.Mul(1.5).Sub(ownerVel).Mul(0.5))))) + e.data.Move(owner.Position(), e.data.Rotation(), false) + e.data.SetVelocity(vel.Add(ownerVel.Add(dV.Mul(0.1).Add(dV.Mul(1.5).Sub(ownerVel).Mul(0.5))))) } else { - e.data.SetVelocity(e, tx, mgl64.Vec3{ + e.data.SetVelocity(mgl64.Vec3{ vel[0] * f.conf.SidewaysVelocityMultiplier, vel[1] * f.conf.UpwardsAcceleration, vel[2] * f.conf.SidewaysVelocityMultiplier, diff --git a/server/entity/passive.go b/server/entity/passive.go index 7dab7d6a4..267d5701c 100644 --- a/server/entity/passive.go +++ b/server/entity/passive.go @@ -58,7 +58,7 @@ type PassiveBehaviour struct { // Explode adds velocity to a passive entity to blast it away from the // explosion's source. func (p *PassiveBehaviour) Explode(e *Ent, src mgl64.Vec3, impact float64, _ block.ExplosionConfig) { - e.data.SetVelocity(e, e.tx, e.data.Velocity().Add(e.data.Position().Sub(src).Normalize().Mul(impact))) + e.data.SetVelocity(e.data.Velocity().Add(e.data.Position().Sub(src).Normalize().Mul(impact))) } // Fuse returns the leftover time until PassiveBehaviourConfig.Expire is called, @@ -79,8 +79,8 @@ func (p *PassiveBehaviour) Tick(e *Ent, tx *world.Tx) *Movement { } m := p.mc.TickMovement(e, e.data.Position(), e.data.Velocity(), e.data.Rotation(), tx) - e.data.Move(e, tx, m.pos, m.rot, m.onGround) - e.data.SetVelocity(e, tx, m.vel) + e.data.Move(m.pos, m.rot, m.onGround) + e.data.SetVelocity(m.vel) p.fallDistance = math.Max(p.fallDistance-m.dvel[1], 0) p.fuse = p.conf.ExistenceDuration - e.Age() diff --git a/server/entity/projectile.go b/server/entity/projectile.go index cd0e328a5..ae2093766 100644 --- a/server/entity/projectile.go +++ b/server/entity/projectile.go @@ -118,7 +118,7 @@ func (lt *ProjectileBehaviour) Owner() *world.EntityHandle { // Explode adds velocity to a projectile to blast it away from the explosion's // source. func (lt *ProjectileBehaviour) Explode(e *Ent, src mgl64.Vec3, impact float64, _ block.ExplosionConfig) { - e.data.SetVelocity(e, e.tx, e.Velocity().Add(e.Position().Sub(src).Normalize().Mul(impact))) + e.data.SetVelocity(e.Velocity().Add(e.Position().Sub(src).Normalize().Mul(impact))) } // Potion returns the potion.Potion that is applied to an entity if hit by the @@ -150,8 +150,8 @@ func (lt *ProjectileBehaviour) Tick(e *Ent, tx *world.Tx) *Movement { } vel := e.Velocity() m, result := lt.tickMovement(e, tx) - e.data.Move(e, tx, m.pos, m.rot, m.onGround) - e.data.SetVelocity(e, tx, m.vel) + e.data.Move(m.pos, m.rot, m.onGround) + e.data.SetVelocity(m.vel) lt.collisionPos, lt.collided, lt.ageCollided = cube.Pos{}, false, 0 diff --git a/server/player/player.go b/server/player/player.go index ce95b303a..b84b8a4d1 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -861,7 +861,7 @@ func finishDying(_ *world.Tx, e world.Entity) { // position server side so that in the future, the client won't respawn // on the death location when disconnecting. The client should not see // the movement itself yet, though. - p.data.Move(p, p.tx, p.tx.World().Spawn().Vec3(), p.Rotation(), p.onGround) + p.data.Move(p.tx.World().Spawn().Vec3(), p.Rotation(), p.onGround) } } @@ -2032,7 +2032,7 @@ func (p *Player) Teleport(pos mgl64.Vec3) { // teleport teleports the player to a target position in the world. It does not call the Handler of the // player. func (p *Player) teleport(pos mgl64.Vec3) { - p.data.Teleport(p, p.tx, pos) + p.data.Teleport(pos) p.ResetFallDistance() } @@ -2064,7 +2064,7 @@ func (p *Player) Move(deltaPos mgl64.Vec3, deltaYaw, deltaPitch float64) { } return } - p.data.Move(p, p.tx, res, resRot, p.OnGround()) + p.data.Move(res, resRot, p.OnGround()) if deltaPos.Len() <= 3 { // Only update velocity if the player is not moving too fast to prevent potential OOMs. p.data.Vel = deltaPos @@ -2117,7 +2117,7 @@ func (p *Player) Velocity() mgl64.Vec3 { // SetVelocity updates the player's velocity. If there is an attached session, this will just send // the velocity to the player session for the player to update. func (p *Player) SetVelocity(velocity mgl64.Vec3) { - p.data.SetVelocity(p, p.tx, velocity) + p.data.SetVelocity(velocity) } // Rotation returns the yaw and pitch of the player in degrees. Yaw is horizontal rotation (rotation around the @@ -2397,8 +2397,8 @@ func (p *Player) Tick(tx *world.Tx, current int64) { // TODO: Move p.data.Move into p.Move() // p.Move(m.Position().Sub(p.Position()), 0, 0) - p.data.Move(p, tx, m.Position(), m.Rotation(), p.onGround) - p.data.SetVelocity(p, tx, m.Velocity()) + p.data.Move(m.Position(), m.Rotation(), p.onGround) + p.data.SetVelocity(m.Velocity()) } else { p.data.Vel = mgl64.Vec3{} } diff --git a/server/world/entity.go b/server/world/entity.go index b6387f58a..8fc9796cb 100644 --- a/server/world/entity.go +++ b/server/world/entity.go @@ -52,7 +52,7 @@ type EntityHandle struct { weakTxActive bool w *World - data EntityData + data *EntityData // TODO Handler? Handle world change here? } @@ -83,11 +83,11 @@ func (opts EntitySpawnOpts) New(t EntityType, conf EntityConfig) *EntityHandle { opts.ID = uuid.New() clear(opts.ID[:8]) } - handle := &EntityHandle{id: opts.ID, t: t, cond: sync.NewCond(&sync.Mutex{}), worldless: &atomic.Bool{}} + handle := &EntityHandle{id: opts.ID, t: t, cond: sync.NewCond(&sync.Mutex{}), worldless: &atomic.Bool{}, data: &EntityData{}} handle.worldless.Store(true) handle.data.pos, handle.data.rot, handle.data.Vel = opts.Position, opts.Rotation, opts.Velocity handle.data.Name = opts.NameTag - conf.Apply(&handle.data) + conf.Apply(handle.data) return handle } @@ -102,10 +102,10 @@ func NewEntity(t EntityType, conf EntityConfig) *EntityHandle { // entityFromData reads an entity from the decoded NBT data passed and returns // an EntityHandle. func entityFromData(t EntityType, id int64, data map[string]any) *EntityHandle { - handle := &EntityHandle{t: t, cond: sync.NewCond(&sync.Mutex{}), worldless: &atomic.Bool{}} + handle := &EntityHandle{t: t, cond: sync.NewCond(&sync.Mutex{}), worldless: &atomic.Bool{}, data: &EntityData{}} binary.LittleEndian.PutUint64(handle.id[8:], uint64(id)) handle.decodeNBT(data) - t.DecodeNBT(data, &handle.data) + t.DecodeNBT(data, handle.data) return handle } @@ -121,7 +121,8 @@ func (e *EntityHandle) Entity(tx *Tx) (Entity, bool) { if e == nil || e.w != tx.World() { return nil, false } - return e.t.Open(tx, e, &e.data), true + e.data.ent, e.data.tx = e.t.Open(tx, e, e.data), tx + return e.data.ent, true } // mustEntity calls Entity but panics if the worlds do not match. @@ -289,6 +290,9 @@ func (e *EntityHandle) encodeNBT() map[string]any { // EntityData holds data shared by every entity. It is kept in an EntityHandle. type EntityData struct { + ent Entity + tx *Tx + pos, Vel mgl64.Vec3 rot cube.Rotation Name string @@ -302,11 +306,11 @@ func (edata *EntityData) Velocity() mgl64.Vec3 { return edata.Vel } -func (edata *EntityData) SetVelocity(e Entity, tx *Tx, vel mgl64.Vec3) { +func (edata *EntityData) SetVelocity(vel mgl64.Vec3) { if !vel.ApproxEqualThreshold(edata.Vel, epsilon) { // Only send velocity if the delta is big enough. - for _, v := range tx.Viewers(edata.pos) { - v.ViewEntityVelocity(e, vel) + for _, v := range edata.tx.Viewers(edata.pos) { + v.ViewEntityVelocity(edata.ent, vel) } } edata.Vel = vel @@ -320,30 +324,30 @@ func (edata *EntityData) Rotation() cube.Rotation { return edata.rot } -func (edata *EntityData) Teleport(e Entity, tx *Tx, pos mgl64.Vec3) { - edata.SetVelocity(e, tx, mgl64.Vec3{}) - for _, v := range tx.Viewers(edata.pos) { - v.ViewEntityTeleport(e, pos) +func (edata *EntityData) Teleport(pos mgl64.Vec3) { + edata.SetVelocity(mgl64.Vec3{}) + for _, v := range edata.tx.Viewers(edata.pos) { + v.ViewEntityTeleport(edata.ent, pos) } - edata.setPosition(e, tx, pos, edata.rot) + edata.setPosition(pos, edata.rot) } // epsilon is the epsilon used for thresholds for change used for change in // position and velocity. const epsilon = 0.001 -func (edata *EntityData) Move(e Entity, tx *Tx, pos mgl64.Vec3, rot cube.Rotation, onGround bool) { +func (edata *EntityData) Move(pos mgl64.Vec3, rot cube.Rotation, onGround bool) { if !pos.ApproxEqualThreshold(edata.pos, epsilon) || !mgl64.Vec2(rot).ApproxEqualThreshold(mgl64.Vec2(edata.rot), epsilon) { // Only send movement if the delta of either rotation or position is // significant enough. - for _, v := range tx.Viewers(edata.pos) { - v.ViewEntityMovement(e, pos, rot, onGround) + for _, v := range edata.tx.Viewers(edata.pos) { + v.ViewEntityMovement(edata.ent, pos, rot, onGround) } } - edata.setPosition(e, tx, pos, rot) + edata.setPosition(pos, rot) } -func (edata *EntityData) setPosition(e Entity, tx *Tx, pos mgl64.Vec3, rot cube.Rotation) { +func (edata *EntityData) setPosition(pos mgl64.Vec3, rot cube.Rotation) { prevChunkPos, chunkPos := chunkPosFromVec3(edata.pos), chunkPosFromVec3(pos) if prevChunkPos == chunkPos { // Entity remains in the same chunk. @@ -352,16 +356,16 @@ func (edata *EntityData) setPosition(e Entity, tx *Tx, pos mgl64.Vec3, rot cube. // The entity's chunk position changed: Move it from the old chunk to the // new chunk. - prevChunk, chunk := tx.World().chunk(prevChunkPos), tx.World().chunk(chunkPos) + prevChunk, chunk := edata.tx.World().chunk(prevChunkPos), edata.tx.World().chunk(chunkPos) - chunk.Entities = append(chunk.Entities, e.H()) - prevChunk.Entities = sliceutil.DeleteVal(prevChunk.Entities, e.H()) + chunk.Entities = append(chunk.Entities, edata.ent.H()) + prevChunk.Entities = sliceutil.DeleteVal(prevChunk.Entities, edata.ent.H()) for _, viewer := range prevChunk.viewers { if slices.Index(chunk.viewers, viewer) == -1 { // First we hide the entity from all viewers that were previously // viewing it, but no longer are. - viewer.HideEntity(e) + viewer.HideEntity(edata.ent) } } edata.pos, edata.rot = pos, rot @@ -369,7 +373,7 @@ func (edata *EntityData) setPosition(e Entity, tx *Tx, pos mgl64.Vec3, rot cube. if slices.Index(prevChunk.viewers, viewer) == -1 { // Then we show the entity to all loaders that are now viewing the // entity in the new chunk. - showEntity(e, viewer) + showEntity(edata.ent, viewer) } } } diff --git a/server/world/world.go b/server/world/world.go index 28532813e..db9c32d40 100644 --- a/server/world/world.go +++ b/server/world/world.go @@ -1240,7 +1240,7 @@ func (w *World) columnTo(col *Column, pos ChunkPos) *chunk.Column { } for _, e := range col.Entities { data := e.encodeNBT() - maps.Copy(data, e.t.EncodeNBT(&e.data)) + maps.Copy(data, e.t.EncodeNBT(e.data)) data["identifier"] = e.t.EncodeEntity() c.Entities = append(c.Entities, chunk.Entity{ID: int64(binary.LittleEndian.Uint64(e.id[8:])), Data: data}) }