129 lines
3.0 KiB
Go
129 lines
3.0 KiB
Go
package types
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
|
|
pb "gitea.boner.be/bdnugget/goonserver/actions"
|
|
rl "github.com/gen2brain/raylib-go/raylib"
|
|
)
|
|
|
|
type Player struct {
|
|
sync.RWMutex
|
|
PosActual rl.Vector3
|
|
PosTile Tile
|
|
TargetPath []Tile
|
|
ActionQueue []*pb.Action
|
|
Speed float32
|
|
ID int32
|
|
IsMoving bool
|
|
AnimationFrame int32
|
|
LastAnimUpdate time.Time
|
|
LastUpdateTime time.Time
|
|
InterpolationProgress float32
|
|
FloatingMessage *FloatingMessage
|
|
QuitDone chan struct{}
|
|
UserData interface{}
|
|
Model rl.Model
|
|
Texture rl.Texture2D
|
|
Username string
|
|
}
|
|
|
|
func (p *Player) MoveTowards(target Tile, deltaTime float32, mapGrid [][]Tile) {
|
|
p.Lock()
|
|
defer p.Unlock()
|
|
|
|
targetPos := rl.Vector3{
|
|
X: float32(target.X * TileSize),
|
|
Y: mapGrid[target.X][target.Y].Height * TileHeight,
|
|
Z: float32(target.Y * TileSize),
|
|
}
|
|
|
|
direction := rl.Vector3Subtract(targetPos, p.PosActual)
|
|
distance := rl.Vector3Length(direction)
|
|
|
|
if distance > 1.0 {
|
|
wasMoving := p.IsMoving
|
|
p.IsMoving = true
|
|
|
|
if !wasMoving {
|
|
p.AnimationFrame = 0
|
|
}
|
|
|
|
oldFrame := p.AnimationFrame
|
|
p.AnimationFrame += int32(deltaTime * 60)
|
|
rl.TraceLog(rl.LogInfo, "Walk frame update: %d -> %d (delta: %f)",
|
|
oldFrame, p.AnimationFrame, deltaTime)
|
|
} else {
|
|
wasMoving := p.IsMoving
|
|
p.IsMoving = false
|
|
|
|
if wasMoving {
|
|
p.AnimationFrame = 0
|
|
}
|
|
|
|
oldFrame := p.AnimationFrame
|
|
p.AnimationFrame += int32(deltaTime * 60)
|
|
rl.TraceLog(rl.LogInfo, "Idle frame update: %d -> %d (delta: %f)",
|
|
oldFrame, p.AnimationFrame, deltaTime)
|
|
}
|
|
|
|
if distance > 0 {
|
|
direction = rl.Vector3Scale(direction, p.Speed*deltaTime/distance)
|
|
}
|
|
|
|
if distance > 1.0 {
|
|
p.PosActual = rl.Vector3Add(p.PosActual, direction)
|
|
} else {
|
|
p.PosActual = targetPos
|
|
p.PosTile = target
|
|
if len(p.TargetPath) > 1 {
|
|
p.TargetPath = p.TargetPath[1:]
|
|
}
|
|
}
|
|
}
|
|
|
|
func NewPlayer(state *pb.PlayerState) *Player {
|
|
return &Player{
|
|
PosActual: rl.Vector3{
|
|
X: float32(state.X * TileSize),
|
|
Y: float32(state.Y * TileHeight),
|
|
Z: float32(state.Y * TileSize),
|
|
},
|
|
PosTile: Tile{X: int(state.X), Y: int(state.Y)},
|
|
Speed: 50.0,
|
|
ID: state.PlayerId,
|
|
IsMoving: false,
|
|
AnimationFrame: 0,
|
|
LastAnimUpdate: time.Now(),
|
|
}
|
|
}
|
|
|
|
func (p *Player) UpdatePosition(state *pb.PlayerState, tickRate time.Duration) {
|
|
p.Lock()
|
|
defer p.Unlock()
|
|
|
|
targetTile := Tile{X: int(state.X), Y: int(state.Y)}
|
|
if p.PosTile != targetTile {
|
|
p.PosTile = targetTile
|
|
p.LastUpdateTime = time.Now()
|
|
p.InterpolationProgress = 0
|
|
p.TargetPath = []Tile{targetTile}
|
|
}
|
|
}
|
|
|
|
func (p *Player) ForceResync(state *pb.PlayerState) {
|
|
p.Lock()
|
|
defer p.Unlock()
|
|
|
|
p.PosTile = Tile{X: int(state.X), Y: int(state.Y)}
|
|
p.PosActual = rl.Vector3{
|
|
X: float32(state.X * TileSize),
|
|
Y: float32(state.Y * TileHeight),
|
|
Z: float32(state.Y * TileSize),
|
|
}
|
|
p.TargetPath = nil
|
|
p.ActionQueue = nil
|
|
p.InterpolationProgress = 1.0
|
|
}
|