1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-09 09:20:44 +00:00
OpenDiablo2/d2core/d2map/npc.go

98 lines
2.2 KiB
Go

package d2map
import (
"math/rand"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
)
type NPC struct {
*AnimatedComposite
action int
HasPaths bool
Paths []d2common.Path
path int
isDone bool
repetitions int
}
func CreateNPC(x, y int, object *d2datadict.ObjectLookupRecord, direction int) *NPC {
entity, err := CreateAnimatedComposite(x, y, object, d2resource.PaletteUnits)
if err != nil {
panic(err)
}
result := &NPC{AnimatedComposite: entity, HasPaths: false}
result.SetMode(object.Mode, object.Class, direction)
return result
}
func (v *NPC) Path() d2common.Path {
return v.Paths[v.path]
}
func (v *NPC) NextPath() d2common.Path {
v.path++
if v.path == len(v.Paths) {
v.path = 0
}
return v.Paths[v.path]
}
func (v *NPC) SetPaths(paths []d2common.Path) {
v.Paths = paths
v.HasPaths = len(paths) > 0
v.isDone = true
}
func (v *NPC) Advance(tickTime float64) {
v.Step(tickTime)
v.AnimatedComposite.Advance(tickTime)
if v.HasPaths && v.wait() {
// If at the target, set target to the next path.
v.isDone = false
path := v.NextPath()
v.SetTarget(
float64(path.X),
float64(path.Y),
v.next,
)
v.action = path.Action
}
}
// If an npc has a path to pause at each location.
// Waits for animation to end and all repetitions to be exhausted.
func (v *NPC) wait() bool {
return v.isDone && v.composite.GetPlayedCount() > v.repetitions
}
func (v *NPC) next() {
v.isDone = true
v.repetitions = 3 + rand.Intn(5)
newAnimationMode := d2enum.AnimationModeObjectNeutral
// TODO: Figure out what 1-3 are for, 4 is correct.
switch v.action {
case 1:
newAnimationMode = d2enum.AnimationModeMonsterNeutral
case 2:
newAnimationMode = d2enum.AnimationModeMonsterNeutral
case 3:
newAnimationMode = d2enum.AnimationModeMonsterNeutral
case 4:
newAnimationMode = d2enum.AnimationModeMonsterSkill1
v.repetitions = 0
default:
v.repetitions = 0
}
if v.animationMode != newAnimationMode.String() {
v.SetMode(newAnimationMode.String(), v.weaponClass, v.direction)
}
}