Prevent player movement and casting if current spell cast is not fini… (#729)

* Prevent player movement and casting if current spell cast is not finished yet

* Properly format the fields of Player struct

Co-authored-by: Presiyan Ivanov <presiyan-ivanov@users.noreply.github.com>
This commit is contained in:
presiyan-ivanov 2020-09-14 21:49:31 +03:00 committed by GitHub
parent 7f6ae1b785
commit 8a670d7482
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 38 deletions

View File

@ -453,8 +453,10 @@ func (a *App) allocRate(totalAlloc uint64, fps float64) float64 {
}
func (a *App) dumpHeap() {
if err := os.Mkdir("./pprof/", 0750); err != nil {
log.Fatal(err)
if _, err := os.Stat("./pprof/"); os.IsNotExist(err) {
if err := os.Mkdir("./pprof/", 0750); err != nil {
log.Fatal(err)
}
}
fileOut, _ := os.Create("./pprof/heap.pprof")

View File

@ -57,6 +57,12 @@ func (m *mapEntity) ClearPath() {
m.path = nil
}
// StopMoving will clear the path and target of the entity.
func (m *mapEntity) StopMoving() {
m.ClearPath()
m.setTarget(m.Position, nil)
}
// SetSpeed sets the entity movement speed.
func (m *mapEntity) SetSpeed(speed float64) {
m.Speed = speed

View File

@ -14,20 +14,18 @@ import (
// Player is the player character entity.
type Player struct {
mapEntity
name string
animationMode string
composite *d2asset.Composite
Equipment *d2inventory.CharacterEquipment
Stats *d2hero.HeroStatsState
Class d2enum.Hero
lastPathSize int
isInTown bool
isRunToggled bool
isRunning bool
isCasting bool
// nameLabel d2ui.Label
name string
animationMode string
composite *d2asset.Composite
Equipment *d2inventory.CharacterEquipment
Stats *d2hero.HeroStatsState
Class d2enum.Hero
lastPathSize int
isInTown bool
isRunToggled bool
isRunning bool
isCasting bool
onFinishedCasting func()
}
// run speed should be walkspeed * 1.5, since in the original game it is 6 yards walk and 9 yards run.
@ -84,6 +82,11 @@ func (p *Player) Advance(tickTime float64) {
if p.IsCasting() && p.composite.GetPlayedCount() >= 1 {
p.isCasting = false
if p.onFinishedCasting != nil {
p.onFinishedCasting()
p.onFinishedCasting = nil
}
if err := p.SetAnimationMode(p.GetAnimationMode()); err != nil {
fmt.Printf("failed to set animationMode to: %d, err: %v\n", p.GetAnimationMode(), err)
}
@ -162,6 +165,11 @@ func (p *Player) rotate(direction int) {
}
}
// SetDirection will rotate the player and change the animation
func (p *Player) SetDirection(direction int) {
p.rotate(direction)
}
// Name returns the player name.
func (p *Player) Name() string {
return p.name
@ -172,10 +180,11 @@ func (p *Player) IsCasting() bool {
return p.isCasting
}
// SetCasting sets a flag indicating the player is casting a skill and
// StartCasting sets a flag indicating the player is casting a skill and
// sets the animation mode to the casting animation.
func (p *Player) SetCasting() {
func (p *Player) StartCasting(onFinishedCasting func()) {
p.isCasting = true
p.onFinishedCasting = onFinishedCasting
if err := p.SetAnimationMode(d2enum.PlayerAnimationModeCast); err != nil {
fmtStr := "failed to set animationMode of player: %s to: %d, err: %v\n"
fmt.Printf(fmtStr, p.ID(), d2enum.PlayerAnimationModeCast, err)

View File

@ -293,7 +293,7 @@ func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
shouldDoLeft := lastLeft >= mouseBtnActionsTreshhold
shouldDoRight := lastRight >= mouseBtnActionsTreshhold
if isLeft && shouldDoLeft && inRect {
if isLeft && shouldDoLeft && inRect && !g.hero.IsCasting() {
g.lastLeftBtnActionTime = now
g.inputListener.OnPlayerMove(px, py)
@ -315,7 +315,7 @@ func (g *GameControls) OnMouseButtonRepeat(event d2interface.MouseEvent) bool {
return true
}
if isRight && shouldDoRight && inRect {
if isRight && shouldDoRight && inRect && !g.hero.IsCasting() {
g.lastRightBtnActionTime = now
g.inputListener.OnPlayerCast(g.missileID, px, py)
@ -360,7 +360,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
px = float64(int(px*10)) / 10.0
py = float64(int(py*10)) / 10.0
if event.Button() == d2enum.MouseButtonLeft && !g.isInActiveMenusRect(mx, my) {
if event.Button() == d2enum.MouseButtonLeft && !g.isInActiveMenusRect(mx, my) && !g.hero.IsCasting() {
g.lastLeftBtnActionTime = d2util.Now()
g.inputListener.OnPlayerMove(px, py)
@ -368,7 +368,7 @@ func (g *GameControls) OnMouseButtonDown(event d2interface.MouseEvent) bool {
return true
}
if event.Button() == d2enum.MouseButtonRight && !g.isInActiveMenusRect(mx, my) {
if event.Button() == d2enum.MouseButtonRight && !g.isInActiveMenusRect(mx, my) && !g.hero.IsCasting() {
g.lastRightBtnActionTime = d2util.Now()
g.inputListener.OnPlayerCast(g.missileID, px, py)

View File

@ -229,12 +229,7 @@ func (g *GameClient) handleMovePlayerPacket(packet d2netpacket.NetPacket) error
return
}
regionType := tile.RegionType
if regionType == d2enum.RegionAct1Town {
player.SetIsInTown(true)
} else {
player.SetIsInTown(false)
}
player.SetIsInTown(tile.RegionType == d2enum.RegionAct1Town)
err := player.SetAnimationMode(player.GetAnimationMode())
@ -255,9 +250,20 @@ func (g *GameClient) handleCastSkillPacket(packet d2netpacket.NetPacket) error {
}
player := g.Players[playerCast.SourceEntityID]
player.StopMoving()
player.SetCasting()
player.ClearPath()
castX := playerCast.TargetX * numSubtilesPerTile
castY := playerCast.TargetY * numSubtilesPerTile
rads := d2math.GetRadiansBetween(
player.Position.X(),
player.Position.Y(),
castX,
castY,
)
direction := player.Position.DirectionTo(*d2vector.NewVector(castX, castY))
player.SetDirection(direction)
// currently hardcoded to missile skill
missile, err := g.MapEngine.NewMissile(
@ -270,18 +276,13 @@ func (g *GameClient) handleCastSkillPacket(packet d2netpacket.NetPacket) error {
return err
}
rads := d2math.GetRadiansBetween(
player.Position.X(),
player.Position.Y(),
playerCast.TargetX*numSubtilesPerTile,
playerCast.TargetY*numSubtilesPerTile,
)
missile.SetRadians(rads, func() {
g.MapEngine.RemoveEntity(missile)
})
g.MapEngine.AddEntity(missile)
player.StartCasting(func() {
g.MapEngine.AddEntity(missile)
})
return nil
}