412 missle animation (#470)

* 412 - move missle code to game_client and add animation, still buggy

* mostly working casting animation that cancels path

Co-authored-by: carrelda@Davids-MacBook-Pro.local <carrelda@Davids-MacBook-Pro.local>
This commit is contained in:
David Carrell 2020-06-26 19:03:00 -05:00 committed by GitHub
parent 1ca534cc13
commit c6721432a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 30 deletions

View File

@ -209,7 +209,7 @@ func (m *MapEngine) RemoveEntity(entity d2mapentity.MapEntity) {
if entity == nil {
return
}
panic("Removing entities is not currently implemented")
//panic("Removing entities is not currently implemented")
//m.entities.Remove(entity)
}

View File

@ -55,6 +55,10 @@ func (m *mapEntity) SetPath(path []d2astar.Pather, done func()) {
m.done = done
}
func (m *mapEntity) ClearPath() {
m.path = nil
}
func (m *mapEntity) SetSpeed(speed float64) {
m.Speed = speed
}
@ -173,7 +177,7 @@ func (m *mapEntity) GetPosition() (float64, float64) {
}
func (m *mapEntity) GetPositionF() (float64, float64) {
return float64(m.TileX) + (float64(m.subcellX)/5.0), float64(m.TileY) + (float64(m.subcellY)/5.0)
return float64(m.TileX) + (float64(m.subcellX) / 5.0), float64(m.TileY) + (float64(m.subcellY) / 5.0)
}
func (m *mapEntity) Name() string {

View File

@ -28,6 +28,7 @@ type Player struct {
animationMode string
isRunToggled bool
isRunning bool
isCasting bool
}
// run speed should be walkspeed * 1.5, since in the original game it is 6 yards walk and 9 yards run.
@ -117,6 +118,10 @@ func (p Player) IsInTown() bool {
func (v *Player) Advance(tickTime float64) {
v.Step(tickTime)
if v.IsCasting() && v.composite.GetPlayedCount() >= 1 {
v.isCasting = false
v.SetAnimationMode(v.GetAnimationMode().String())
}
v.composite.Advance(tickTime)
if v.lastPathSize != len(v.path) {
v.lastPathSize = len(v.path)
@ -170,6 +175,10 @@ func (v *Player) GetAnimationMode() d2enum.PlayerAnimationMode {
return d2enum.AnimationModePlayerWalk
}
if v.IsCasting() {
return d2enum.AnimationModePlayerCast
}
return d2enum.AnimationModePlayerNeutral
}
@ -189,3 +198,12 @@ func (v *Player) rotate(direction int) {
func (v *Player) Name() string {
return v.name
}
func (v *Player) IsCasting() bool {
return v.isCasting
}
func (v *Player) SetCasting() {
v.isCasting = true
v.SetAnimationMode(d2enum.AnimationModePlayerCast.String())
}

View File

@ -335,6 +335,7 @@ func (m *EscapeMenu) showLayout(id layoutID) {
if id == saveLayoutID {
mainMenu := CreateMainMenu()
mainMenu.SetScreenMode(ScreenModeMainMenu)
d2screen.SetNextScreen(mainMenu)
return
}

View File

@ -135,3 +135,7 @@ func (v *Game) OnPlayerMove(x, y float64) {
heroPosY := v.localPlayer.LocationY / 5.0
v.gameClient.SendPacketToServer(d2netpacket.CreateMovePlayerPacket(v.gameClient.PlayerId, heroPosX, heroPosY, x, y))
}
func (v *Game) OnPlayerCast(missleID int, targetX, targetY float64) {
v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerId, missleID, targetX, targetY))
}

View File

@ -7,7 +7,6 @@ import (
"time"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
@ -197,7 +196,7 @@ func (g *GameControls) OnMouseButtonRepeat(event d2input.MouseEvent) bool {
if event.Button == d2input.MouseButtonRight && now-lastRightBtnActionTime >= mouseBtnActionsTreshhold && !g.isInActiveMenusRect(event.X, event.Y) {
lastRightBtnActionTime = now
g.ShootMissile(px, py)
g.inputListener.OnPlayerCast(missileID, px, py)
return true
}
@ -241,37 +240,13 @@ func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
if event.Button == d2input.MouseButtonRight && !g.isInActiveMenusRect(mx, my) {
lastRightBtnActionTime = d2common.Now()
return g.ShootMissile(px, py)
g.inputListener.OnPlayerCast(missileID, px, py)
return true
}
return false
}
func (g *GameControls) ShootMissile(px float64, py float64) bool {
missile, err := d2mapentity.CreateMissile(
int(g.hero.LocationX),
int(g.hero.LocationY),
d2datadict.Missiles[missileID],
)
if err != nil {
return false
}
rads := d2common.GetRadiansBetween(
g.hero.LocationX,
g.hero.LocationY,
px*5,
py*5,
)
missile.SetRadians(rads, func() {
g.mapEngine.RemoveEntity(missile)
})
g.mapEngine.AddEntity(missile)
return true
}
func (g *GameControls) Load() {
animation, _ := d2asset.LoadAnimation(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
g.globeSprite, _ = d2ui.LoadSprite(animation)

View File

@ -2,4 +2,5 @@ package d2player
type InputCallbackListener interface {
OnPlayerMove(x, y float64)
OnPlayerCast(skillID int, x, y float64)
}

View File

@ -5,6 +5,9 @@ import (
"log"
"os"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapgen"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
@ -103,6 +106,33 @@ func (g *GameClient) OnPacketReceived(packet d2netpacket.NetPacket) error {
player.SetAnimationMode(player.GetAnimationMode().String())
})
}
case d2netpackettype.CastSkill:
playerCast := packet.PacketData.(d2netpacket.CastPacket)
player := g.Players[playerCast.SourceEntityID]
player.SetCasting()
player.ClearPath()
// currently hardcoded to missile skill
missile, err := d2mapentity.CreateMissile(
int(player.LocationX),
int(player.LocationY),
d2datadict.Missiles[playerCast.SkillID],
)
if err != nil {
return err
}
rads := d2common.GetRadiansBetween(
player.LocationX,
player.LocationY,
playerCast.TargetX*5,
playerCast.TargetY*5,
)
missile.SetRadians(rads, func() {
g.MapEngine.RemoveEntity(missile)
})
g.MapEngine.AddEntity(missile)
case d2netpackettype.Ping:
g.clientConnection.SendPacketToServer(d2netpacket.CreatePongPacket(g.PlayerId))
case d2netpackettype.ServerClosed:

View File

@ -16,4 +16,5 @@ const (
Ping // Ping message type
Pong // Pong message type
ServerClosed // Local host has closed the server
CastSkill // Sent to the client or server to indicate entity casting skill
)

View File

@ -0,0 +1,26 @@
package d2netpacket
import "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2netpacket/d2netpackettype"
// TODO: Need to handle being on different maps
type CastPacket struct {
SourceEntityID string `json:"sourceEntityId"`
SkillID int `json:"skillId"`
TargetX float64 `json:"targetX"`
TargetY float64 `json:"targetY"`
TargetEntityID string `json:"targetEntityId"`
}
func CreateCastPacket(entityID string, skillID int, targetX, targetY float64) NetPacket {
return NetPacket{
PacketType: d2netpackettype.CastSkill,
PacketData: CastPacket{
SourceEntityID: entityID,
SkillID: skillID,
TargetX: targetX,
TargetY: targetY,
TargetEntityID: "", // TODO implement targeting entities
},
}
}

View File

@ -204,6 +204,10 @@ func OnPacketReceived(client ClientConnection, packet d2netpacket.NetPacket) err
for _, player := range singletonServer.clientConnections {
player.SendPacketToClient(packet)
}
case d2netpackettype.CastSkill:
for _, player := range singletonServer.clientConnections {
player.SendPacketToClient(packet)
}
}
return nil
}