diff --git a/d2core/d2asset/composite.go b/d2core/d2asset/composite.go index 6cb941d2..6fb70387 100644 --- a/d2core/d2asset/composite.go +++ b/d2core/d2asset/composite.go @@ -152,12 +152,43 @@ func (c *Composite) GetPlayedCount() int { return c.mode.playedCount } +// SetPlayLoop turns on or off animation looping +func (c *Composite) SetPlayLoop(loop bool) { + for layerIdx := range c.mode.layers { + layer := c.mode.layers[layerIdx] + if layer != nil { + layer.SetPlayLoop(loop) + } + } +} + +// SetSubLoop sets a loop to be between the specified frame indices +func (c *Composite) SetSubLoop(startFrame, endFrame int) { + for layerIdx := range c.mode.layers { + layer := c.mode.layers[layerIdx] + if layer != nil { + layer.SetSubLoop(startFrame, endFrame) + } + } +} + +// SetCurrentFrame sets the current frame index of the animation +func (c *Composite) SetCurrentFrame(frame int) { + for layerIdx := range c.mode.layers { + layer := c.mode.layers[layerIdx] + if layer != nil { + layer.SetCurrentFrame(frame) + } + } +} + func (c *Composite) resetPlayedCount() { if c.mode != nil { c.mode.playedCount = 0 } } + type compositeMode struct { cof *d2cof.COF animationMode string diff --git a/d2core/d2object/init_function.go b/d2core/d2object/init_function.go index 6429f6c5..78c377d8 100644 --- a/d2core/d2object/init_function.go +++ b/d2core/d2object/init_function.go @@ -1,6 +1,8 @@ package d2object import ( + "math/rand" + "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" ) @@ -10,6 +12,7 @@ func initObject(ob *Object) bool { 8: initTorch, 14: initTorch, 17: initWaypoint, + 34: initTorchRnd, } fun, ok := funcs[ob.objectRecord.InitFn] @@ -25,13 +28,24 @@ func initObject(ob *Object) bool { // Initializes torch/brazier type objects func initTorch(ob *Object) { if ob.objectRecord.HasAnimationMode[d2enum.AnimationModeObjectOperating] { - ob.setMode("ON", 0) + ob.setMode("ON", 0, true) } } func initWaypoint(ob *Object) { // Turn these on unconditionally for now, they look nice :) if ob.objectRecord.HasAnimationMode[d2enum.AnimationModeObjectOperating] { - ob.setMode("ON", 0) + ob.setMode("ON", 0, true) + } +} + +// Randomly spawns in either NU or OP +func initTorchRnd(ob *Object) { + n := rand.Intn(2) + + if n > 0 { + ob.setMode("NU", 0, true) + } else { + ob.setMode("OP", 0, true) } } diff --git a/d2core/d2object/object.go b/d2core/d2object/object.go index 3c60df2c..b85acd89 100644 --- a/d2core/d2object/object.go +++ b/d2core/d2object/object.go @@ -3,6 +3,7 @@ package d2object import ( "math" + "math/rand" "github.com/OpenDiablo2/OpenDiablo2/d2common" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict" @@ -49,7 +50,7 @@ func CreateObject(x, y int, objectRec *d2datadict.ObjectRecord, palettePath stri entity.composite = composite - entity.setMode("NU", 0) + entity.setMode("NU", 0, false) initObject(entity) @@ -57,7 +58,7 @@ func CreateObject(x, y int, objectRec *d2datadict.ObjectRecord, palettePath stri } // setMode changes the graphical mode of this animated entity -func (ob *Object) setMode(animationMode string, direction int) error { +func (ob *Object) setMode(animationMode string, direction int, randomFrame bool) error { err := ob.composite.SetMode(animationMode, "HTH") if err != nil { return err @@ -74,6 +75,20 @@ func (ob *Object) setMode(animationMode string, direction int) error { ob.composite.SetAnimSpeed(speed) } + frameCount := ob.objectRecord.FrameCount[mode] + + if frameCount != 0 { + ob.composite.SetSubLoop(0, frameCount) + } + + ob.composite.SetPlayLoop(ob.objectRecord.CycleAnimation[mode]) + ob.composite.SetCurrentFrame(ob.objectRecord.StartFrame[mode]) + + if randomFrame { + n := rand.Intn(frameCount) + ob.composite.SetCurrentFrame(n) + } + return err }