Skip to content

Commit

Permalink
Use missile range and subloop (OpenDiablo2#311)
Browse files Browse the repository at this point in the history
Turn on blending.  Calculate target using based on range and angle of hero to click.
  • Loading branch information
nicholas-eden authored Feb 23, 2020
1 parent 423cef3 commit f601449
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
8 changes: 8 additions & 0 deletions d2common/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ func GetAngleBetween(p1X, p1Y, p2X, p2Y float64) int {
return iResult
}

// GetRadiansBetween returns the radians between two points. 0rad is facing to the right.
func GetRadiansBetween(p1X, p1Y, p2X, p2Y float64) float64 {
deltaY := p2Y - p1Y
deltaX := p2X - p1X

return math.Atan2(deltaY, deltaX)
}

// AlmostEqual returns true if two values are within threshold from each other
func AlmostEqual(a, b, threshold float64) bool {
return math.Abs(a-b) <= threshold
Expand Down
34 changes: 25 additions & 9 deletions d2core/d2asset/animation.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ type Animation struct {
compositeMode d2render.CompositeMode
colorMod color.Color

playMode playMode
playLength float64
playLoop bool
playMode playMode
playLength float64
playLoop bool
hasSubLoop bool // runs after first animation ends
subStartingFrame int
subEndingFrame int
}

func createAnimationFromDCC(dcc *d2dcc.DCC, palette *d2datadict.PaletteRec, transparency int) (*Animation, error) {
Expand Down Expand Up @@ -150,6 +153,12 @@ func (a *Animation) Clone() *Animation {
return &animation
}

func (a *Animation) SetSubLoop(startFrame, EndFrame int) {
a.subStartingFrame = startFrame
a.subEndingFrame = EndFrame
a.hasSubLoop = true
}

func (a *Animation) Advance(elapsed float64) error {
if a.playMode == playModePause {
return nil
Expand All @@ -162,26 +171,33 @@ func (a *Animation) Advance(elapsed float64) error {
a.lastFrameTime -= float64(framesAdvanced) * frameLength

for i := 0; i < framesAdvanced; i++ {
startIndex := 0
endIndex := frameCount
if a.hasSubLoop && a.playedCount > 0 {
startIndex = a.subStartingFrame
endIndex = a.subEndingFrame
}

switch a.playMode {
case playModeForward:
a.frameIndex++
if a.frameIndex >= frameCount {
if a.frameIndex >= endIndex {
a.playedCount++
if a.playLoop {
a.frameIndex = 0
a.frameIndex = startIndex
} else {
a.frameIndex = frameCount - 1
a.frameIndex = endIndex - 1
break
}
}
case playModeBackward:
a.frameIndex--
if a.frameIndex < 0 {
if a.frameIndex < startIndex {
a.playedCount++
if a.playLoop {
a.frameIndex = frameCount - 1
a.frameIndex = endIndex - 1
} else {
a.frameIndex = 0
a.frameIndex = startIndex
break
}
}
Expand Down
19 changes: 18 additions & 1 deletion d2core/d2map/missile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"math"
)

type Missile struct {
*AnimatedEntity
record *d2datadict.MissileRecord
record *d2datadict.MissileRecord
}

func CreateMissile(x, y int, record *d2datadict.MissileRecord) (*Missile, error) {
Expand All @@ -21,6 +22,13 @@ func CreateMissile(x, y int, record *d2datadict.MissileRecord) (*Missile, error)
return nil, err
}

if record.Animation.HasSubLoop {
animation.SetSubLoop(record.Animation.SubStartingFrame, record.Animation.SubEndingFrame)
}

animation.SetBlend(true)
//animation.SetPlaySpeed(float64(record.Animation.AnimationSpeed))
animation.SetPlayLoop(record.Animation.LoopAnimation)
animation.PlayForward()
entity := CreateAnimatedEntity(x, y, animation)

Expand All @@ -32,6 +40,15 @@ func CreateMissile(x, y int, record *d2datadict.MissileRecord) (*Missile, error)
return result, nil
}

func (m *Missile) SetRadians(angle float64, done func()) {
r := float64(m.record.Range)

x := m.LocationX + (r * math.Cos(angle))
y := m.LocationY + (r * math.Sin(angle))

m.SetTarget(x, y, done)
}

func (m *Missile) Advance(tickTime float64) {
// TODO: collision detection
m.Step(tickTime)
Expand Down
9 changes: 8 additions & 1 deletion d2game/d2player/game_controls.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package d2player

import (
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
Expand Down Expand Up @@ -90,7 +91,13 @@ func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
return false
}

missile.SetTarget(px*5, py*5, func() {
rads := d2common.GetRadiansBetween(
g.hero.AnimatedComposite.LocationX,
g.hero.AnimatedComposite.LocationY,
px*5,
py*5,
)
missile.SetRadians(rads, func() {
g.mapEngine.RemoveEntity(missile)
})

Expand Down

0 comments on commit f601449

Please sign in to comment.