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

Use missile range and subloop (#311)

Turn on blending.  Calculate target using based on range and angle of hero to click.
This commit is contained in:
nicholas-eden 2020-02-23 00:23:18 -08:00 committed by GitHub
parent 423cef304d
commit f6014498ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 11 deletions

View File

@ -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

View File

@ -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) {
@ -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
@ -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
}
}

View File

@ -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) {
@ -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)
@ -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)

View File

@ -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"
@ -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)
})