2020-06-21 18:40:37 -04:00
|
|
|
package d2mapentity
|
2020-02-22 20:44:30 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-04-11 14:56:47 -04:00
|
|
|
"math"
|
|
|
|
|
2020-07-18 18:07:13 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
|
|
|
|
2020-02-22 20:44:30 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
2020-07-08 21:57:35 -04:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
2020-02-22 20:44:30 -05:00
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
|
|
|
)
|
|
|
|
|
2020-07-09 16:11:01 -04:00
|
|
|
// Missile is a simple animated entity representing a projectile,
|
|
|
|
// such as a spell or arrow.
|
2020-02-22 20:44:30 -05:00
|
|
|
type Missile struct {
|
|
|
|
*AnimatedEntity
|
2020-02-23 03:23:18 -05:00
|
|
|
record *d2datadict.MissileRecord
|
2020-02-22 20:44:30 -05:00
|
|
|
}
|
|
|
|
|
2020-07-21 08:51:09 -04:00
|
|
|
func (m *Missile) GetPosition() d2vector.Position {
|
|
|
|
return m.AnimatedEntity.Position
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Missile) GetVelocity() d2vector.Vector {
|
|
|
|
return m.AnimatedEntity.velocity
|
|
|
|
}
|
|
|
|
|
2020-07-09 16:11:01 -04:00
|
|
|
// CreateMissile creates a new Missile and initializes it's animation.
|
2020-02-22 20:44:30 -05:00
|
|
|
func CreateMissile(x, y int, record *d2datadict.MissileRecord) (*Missile, error) {
|
|
|
|
animation, err := d2asset.LoadAnimation(
|
|
|
|
fmt.Sprintf("%s/%s.dcc", d2resource.MissileData, record.Animation.CelFileName),
|
|
|
|
d2resource.PaletteUnits,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-02-23 03:23:18 -05:00
|
|
|
if record.Animation.HasSubLoop {
|
|
|
|
animation.SetSubLoop(record.Animation.SubStartingFrame, record.Animation.SubEndingFrame)
|
|
|
|
}
|
|
|
|
|
2020-07-08 21:57:35 -04:00
|
|
|
animation.SetEffect(d2enum.DrawEffectModulate)
|
2020-07-13 09:06:50 -04:00
|
|
|
// animation.SetPlaySpeed(float64(record.Animation.AnimationSpeed))
|
2020-02-23 03:23:18 -05:00
|
|
|
animation.SetPlayLoop(record.Animation.LoopAnimation)
|
2020-02-22 20:44:30 -05:00
|
|
|
animation.PlayForward()
|
|
|
|
entity := CreateAnimatedEntity(x, y, animation)
|
|
|
|
|
|
|
|
result := &Missile{
|
|
|
|
AnimatedEntity: entity,
|
|
|
|
record: record,
|
|
|
|
}
|
|
|
|
result.Speed = float64(record.Velocity)
|
2020-07-09 16:11:01 -04:00
|
|
|
|
2020-02-22 20:44:30 -05:00
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2020-07-09 16:11:01 -04:00
|
|
|
// SetRadians adjusts the entity target based on it's range, rotating it's
|
|
|
|
// current destination by the value of angle in radians.
|
2020-02-23 03:23:18 -05:00
|
|
|
func (m *Missile) SetRadians(angle float64, done func()) {
|
|
|
|
r := float64(m.record.Range)
|
|
|
|
|
2020-07-13 09:06:50 -04:00
|
|
|
x := m.Position.X() + (r * math.Cos(angle))
|
|
|
|
y := m.Position.Y() + (r * math.Sin(angle))
|
2020-02-23 03:23:18 -05:00
|
|
|
|
2020-07-18 18:07:13 -04:00
|
|
|
m.setTarget(d2vector.NewPosition(x, y), done)
|
2020-02-23 03:23:18 -05:00
|
|
|
}
|
|
|
|
|
2020-07-09 16:11:01 -04:00
|
|
|
// Advance is called once per frame and processes a
|
|
|
|
// single game tick.
|
2020-02-22 20:44:30 -05:00
|
|
|
func (m *Missile) Advance(tickTime float64) {
|
|
|
|
// TODO: collision detection
|
|
|
|
m.Step(tickTime)
|
|
|
|
m.AnimatedEntity.Advance(tickTime)
|
|
|
|
}
|