mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-05 08:07:51 -05:00
Improve run/walk/neutral animation handling. Initial parsing of Level… (#372)
* Improve run/walk/neutral animation handling. Initial parsing of LevelDetail records. Support for holding mouse buttons. - Run/walk/neutral positions now map to a different animation mode(and speed) depending if in or out of town. - Run/walk toggle which can be activated/deactivated with R key. - Temporary(and incorrect) loading and mapping for LevelDetails records. - Zone change label which shows the level name from LevelDetailsRecord when the player enters a different zone. - Allow holding mouse left/right button to repeatedly generate an action. * Remove duplicate load of LevelDetails. Replace numbers in zone change logic with their corresponding RegionIdType * Move zone change check at the correct place Co-authored-by: Presiyan Ivanov <presiyan-ivanov@users.noreply.github.com>
This commit is contained in:
parent
8dcec1f209
commit
2835ff4cf1
@ -197,6 +197,10 @@ type MouseButtonDownHandler interface {
|
|||||||
OnMouseButtonDown(event MouseEvent) bool
|
OnMouseButtonDown(event MouseEvent) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MouseButtonRepeatHandler interface {
|
||||||
|
OnMouseButtonRepeat(event MouseEvent) bool
|
||||||
|
}
|
||||||
|
|
||||||
type MouseButtonUpHandler interface {
|
type MouseButtonUpHandler interface {
|
||||||
OnMouseButtonUp(event MouseEvent) bool
|
OnMouseButtonUp(event MouseEvent) bool
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,19 @@ func (im *inputManager) advance(elapsed float64) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for button := ebiten.MouseButtonLeft; button < ebiten.MouseButtonMiddle; button++ {
|
||||||
|
if ebiten.IsMouseButtonPressed(button) {
|
||||||
|
event := MouseEvent{eventBase, MouseButton(button)}
|
||||||
|
im.propagate(func(handler Handler) bool {
|
||||||
|
if l, ok := handler.(MouseButtonRepeatHandler); ok {
|
||||||
|
return l.OnMouseButtonRepeat(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if inpututil.IsMouseButtonJustReleased(button) {
|
if inpututil.IsMouseButtonJustReleased(button) {
|
||||||
event := MouseEvent{eventBase, MouseButton(button)}
|
event := MouseEvent{eventBase, MouseButton(button)}
|
||||||
im.propagate(func(handler Handler) bool {
|
im.propagate(func(handler Handler) bool {
|
||||||
|
@ -68,25 +68,51 @@ func (ac *AnimatedComposite) Render(target d2render.Surface) {
|
|||||||
|
|
||||||
// rotate sets direction and changes animation
|
// rotate sets direction and changes animation
|
||||||
func (ac *AnimatedComposite) rotate(angle float64) {
|
func (ac *AnimatedComposite) rotate(angle float64) {
|
||||||
// TODO: Check if is in town and if is player.
|
newAnimationMode := ac.GetAnimationMode().String()
|
||||||
newAnimationMode := ac.composite.GetAnimationMode()
|
|
||||||
if !ac.IsAtTarget() {
|
|
||||||
if ac.player != nil {
|
|
||||||
if ac.player.IsInTown() {
|
|
||||||
newAnimationMode = d2enum.AnimationModePlayerTownWalk.String()
|
|
||||||
} else {
|
|
||||||
newAnimationMode = d2enum.AnimationModePlayerWalk.String()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newAnimationMode = d2enum.AnimationModeMonsterWalk.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
newDirection := angleToDirection(angle)
|
newDirection := angleToDirection(angle)
|
||||||
|
|
||||||
if newAnimationMode != ac.composite.GetAnimationMode() || newDirection != ac.direction {
|
if newAnimationMode != ac.composite.GetAnimationMode() || newDirection != ac.direction {
|
||||||
ac.SetMode(newAnimationMode, ac.weaponClass, newDirection)
|
ac.SetMode(newAnimationMode, ac.weaponClass, newDirection)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AnimatedComposite) GetAnimationMode() d2enum.AnimationMode {
|
||||||
|
var newAnimationMode d2enum.AnimationMode
|
||||||
|
if ac.player != nil {
|
||||||
|
newAnimationMode = ac.GetPlayerAnimationMode()
|
||||||
|
} else {
|
||||||
|
newAnimationMode = ac.GetMonsterAnimationMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
return newAnimationMode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AnimatedComposite) GetPlayerAnimationMode() d2enum.AnimationMode {
|
||||||
|
if ac.player.IsRunning() && !ac.IsAtTarget(){
|
||||||
|
return d2enum.AnimationModePlayerRun
|
||||||
|
}
|
||||||
|
|
||||||
|
if ac.player.IsInTown() {
|
||||||
|
if !ac.IsAtTarget() {
|
||||||
|
return d2enum.AnimationModePlayerTownWalk
|
||||||
|
}
|
||||||
|
|
||||||
|
return d2enum.AnimationModePlayerTownNeutral
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ac.IsAtTarget() {
|
||||||
|
return d2enum.AnimationModePlayerWalk
|
||||||
|
}
|
||||||
|
|
||||||
|
return d2enum.AnimationModePlayerNeutral
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ac *AnimatedComposite) GetMonsterAnimationMode() d2enum.AnimationMode {
|
||||||
|
if !ac.IsAtTarget() {
|
||||||
|
return d2enum.AnimationModeMonsterWalk
|
||||||
|
}
|
||||||
|
|
||||||
|
return d2enum.AnimationModeMonsterNeutral
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *AnimatedComposite) Advance(elapsed float64) {
|
func (ac *AnimatedComposite) Advance(elapsed float64) {
|
||||||
|
@ -53,6 +53,14 @@ func (m *mapEntity) SetPath(path []astar.Pather, done func()) {
|
|||||||
m.done = done
|
m.done = done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mapEntity) SetSpeed(speed float64) {
|
||||||
|
m.Speed = speed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mapEntity) GetSpeed() float64 {
|
||||||
|
return m.Speed
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mapEntity) getStepLength(tickTime float64) (float64, float64) {
|
func (m *mapEntity) getStepLength(tickTime float64) (float64, float64) {
|
||||||
length := tickTime * m.Speed
|
length := tickTime * m.Speed
|
||||||
|
|
||||||
|
@ -21,8 +21,14 @@ type Player struct {
|
|||||||
lastPathSize int
|
lastPathSize int
|
||||||
isInTown bool
|
isInTown bool
|
||||||
animationMode string
|
animationMode string
|
||||||
|
isRunToggled bool
|
||||||
|
isRunning bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run speed should be walkspeed * 1.5, since in the original game it is 6 yards walk and 9 yards run.
|
||||||
|
var baseWalkSpeed = 6.0
|
||||||
|
var baseRunSpeed = 9.0
|
||||||
|
|
||||||
func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero, equipment d2inventory.CharacterEquipment) *Player {
|
func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero, equipment d2inventory.CharacterEquipment) *Player {
|
||||||
object := &d2datadict.ObjectLookupRecord{
|
object := &d2datadict.ObjectLookupRecord{
|
||||||
Mode: d2enum.AnimationModePlayerTownNeutral.String(),
|
Mode: d2enum.AnimationModePlayerTownNeutral.String(),
|
||||||
@ -44,6 +50,7 @@ func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
entity.SetSpeed(baseRunSpeed)
|
||||||
|
|
||||||
result := &Player{
|
result := &Player{
|
||||||
Id: id,
|
Id: id,
|
||||||
@ -52,6 +59,9 @@ func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero
|
|||||||
direction: direction,
|
direction: direction,
|
||||||
Name: name,
|
Name: name,
|
||||||
nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||||
|
isRunToggled: true,
|
||||||
|
isInTown: true,
|
||||||
|
isRunning: true,
|
||||||
}
|
}
|
||||||
result.nameLabel.Alignment = d2ui.LabelAlignCenter
|
result.nameLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
result.nameLabel.SetText(name)
|
result.nameLabel.SetText(name)
|
||||||
@ -68,6 +78,28 @@ func (p *Player) SetIsInTown(isInTown bool) {
|
|||||||
p.isInTown = isInTown
|
p.isInTown = isInTown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) ToggleRunWalk() {
|
||||||
|
p.isRunToggled = !p.isRunToggled
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) IsRunToggled() bool {
|
||||||
|
return p.isRunToggled
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) IsRunning() bool {
|
||||||
|
return p.isRunning
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) SetIsRunning(isRunning bool) {
|
||||||
|
p.isRunning = isRunning
|
||||||
|
|
||||||
|
if isRunning {
|
||||||
|
p.SetSpeed(baseRunSpeed)
|
||||||
|
} else {
|
||||||
|
p.SetSpeed(baseWalkSpeed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (p Player) IsInTown() bool {
|
func (p Player) IsInTown() bool {
|
||||||
return p.isInTown
|
return p.isInTown
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package d2gamescreen
|
package d2gamescreen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client"
|
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client"
|
||||||
@ -22,7 +24,7 @@ type Game struct {
|
|||||||
mapRenderer *d2maprenderer.MapRenderer
|
mapRenderer *d2maprenderer.MapRenderer
|
||||||
gameControls *d2player.GameControls // TODO: Hack
|
gameControls *d2player.GameControls // TODO: Hack
|
||||||
localPlayer *d2mapentity.Player
|
localPlayer *d2mapentity.Player
|
||||||
lastLevelType int
|
lastRegionType d2enum.RegionIdType
|
||||||
ticksSinceLevelCheck float64
|
ticksSinceLevelCheck float64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +33,7 @@ func CreateGame(gameClient *d2client.GameClient) *Game {
|
|||||||
gameClient: gameClient,
|
gameClient: gameClient,
|
||||||
gameControls: nil,
|
gameControls: nil,
|
||||||
localPlayer: nil,
|
localPlayer: nil,
|
||||||
lastLevelType: -1,
|
lastRegionType: d2enum.RegionNone,
|
||||||
ticksSinceLevelCheck: 0,
|
ticksSinceLevelCheck: 0,
|
||||||
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
|
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
|
||||||
}
|
}
|
||||||
@ -61,6 +63,8 @@ func (v *Game) Render(screen d2render.Surface) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hideZoneTextAfterSeconds = 2.0
|
||||||
|
|
||||||
func (v *Game) Advance(tickTime float64) error {
|
func (v *Game) Advance(tickTime float64) error {
|
||||||
if !v.gameControls.InEscapeMenu() || len(v.gameClient.Players) != 1 {
|
if !v.gameControls.InEscapeMenu() || len(v.gameClient.Players) != 1 {
|
||||||
v.gameClient.MapEngine.Advance(tickTime) // TODO: Hack
|
v.gameClient.MapEngine.Advance(tickTime) // TODO: Hack
|
||||||
@ -77,13 +81,22 @@ func (v *Game) Advance(tickTime float64) error {
|
|||||||
tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY)
|
tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY)
|
||||||
if tile != nil {
|
if tile != nil {
|
||||||
switch tile.RegionType {
|
switch tile.RegionType {
|
||||||
case 1: // Rogue encampent
|
case d2enum.RegionAct1Town: // Rogue encampent
|
||||||
v.localPlayer.SetIsInTown(true)
|
v.localPlayer.SetIsInTown(true)
|
||||||
d2audio.PlayBGM("/data/global/music/Act1/town1.wav")
|
d2audio.PlayBGM("/data/global/music/Act1/town1.wav")
|
||||||
case 2: // Blood Moore
|
case d2enum.RegionAct1Wilderness: // Blood Moore
|
||||||
v.localPlayer.SetIsInTown(false)
|
v.localPlayer.SetIsInTown(false)
|
||||||
d2audio.PlayBGM("/data/global/music/Act1/wild.wav")
|
d2audio.PlayBGM("/data/global/music/Act1/wild.wav")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// skip showing zone change text the first time we enter the world
|
||||||
|
if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType {
|
||||||
|
//TODO: Should not be using RegionType as an index - this will return incorrect LevelDetails record for most of the zones.
|
||||||
|
v.gameControls.SetZoneChangeText(fmt.Sprintf("Entering The %s", d2datadict.LevelDetails[int(tile.RegionType)].LevelDisplayName))
|
||||||
|
v.gameControls.ShowZoneChangeText()
|
||||||
|
v.gameControls.HideZoneChangeTextAfter(hideZoneTextAfterSeconds)
|
||||||
|
}
|
||||||
|
v.lastRegionType = tile.RegionType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package d2player
|
package d2player
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"image/color"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
@ -35,10 +38,12 @@ type GameControls struct {
|
|||||||
FreeCam bool
|
FreeCam bool
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
globeSprite *d2ui.Sprite
|
globeSprite *d2ui.Sprite
|
||||||
mainPanel *d2ui.Sprite
|
mainPanel *d2ui.Sprite
|
||||||
menuButton *d2ui.Sprite
|
menuButton *d2ui.Sprite
|
||||||
skillIcon *d2ui.Sprite
|
skillIcon *d2ui.Sprite
|
||||||
|
zoneChangeText *d2ui.Label
|
||||||
|
isZoneTextShown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener) *GameControls {
|
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener) *GameControls {
|
||||||
@ -46,14 +51,19 @@ func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
|
|||||||
missileID = id
|
missileID = id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
label := d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||||
|
label.Color = color.RGBA{R: 255, G: 88, B: 82, A: 255}
|
||||||
|
label.Alignment = d2ui.LabelAlignCenter
|
||||||
|
|
||||||
gc := &GameControls{
|
gc := &GameControls{
|
||||||
hero: hero,
|
hero: hero,
|
||||||
mapEngine: mapEngine,
|
mapEngine: mapEngine,
|
||||||
inputListener: inputListener,
|
inputListener: inputListener,
|
||||||
mapRenderer: mapRenderer,
|
mapRenderer: mapRenderer,
|
||||||
inventory: NewInventory(),
|
inventory: NewInventory(),
|
||||||
heroStats: NewHeroStats(),
|
heroStats: NewHeroStats(),
|
||||||
escapeMenu: NewEscapeMenu(),
|
escapeMenu: NewEscapeMenu(),
|
||||||
|
zoneChangeText: &label,
|
||||||
}
|
}
|
||||||
|
|
||||||
d2term.BindAction("freecam", "toggle free camera movement", func() {
|
d2term.BindAction("freecam", "toggle free camera movement", func() {
|
||||||
@ -116,9 +126,37 @@ func (g *GameControls) OnKeyDown(event d2input.KeyEvent) bool {
|
|||||||
case d2input.KeyC:
|
case d2input.KeyC:
|
||||||
g.heroStats.Toggle()
|
g.heroStats.Toggle()
|
||||||
g.updateLayout()
|
g.updateLayout()
|
||||||
|
case d2input.KeyR:
|
||||||
|
g.hero.ToggleRunWalk()
|
||||||
|
// TODO: change the running menu icon
|
||||||
|
g.hero.SetIsRunning(g.hero.IsRunToggled())
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastLeftBtnActionTime float64 = 0
|
||||||
|
var lastRightBtnActionTime float64 = 0
|
||||||
|
var mouseBtnActionsTreshhold = 0.25
|
||||||
|
|
||||||
|
func (g *GameControls) OnMouseButtonRepeat(event d2input.MouseEvent) bool {
|
||||||
|
px, py := g.mapRenderer.ScreenToWorld(event.X, event.Y)
|
||||||
|
px = float64(int(px*10)) / 10.0
|
||||||
|
py = float64(int(py*10)) / 10.0
|
||||||
|
|
||||||
|
now := d2common.Now()
|
||||||
|
if event.Button == d2input.MouseButtonLeft && now-lastLeftBtnActionTime >= mouseBtnActionsTreshhold {
|
||||||
|
lastLeftBtnActionTime = now
|
||||||
|
g.inputListener.OnPlayerMove(px, py)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if event.Button == d2input.MouseButtonRight && now-lastRightBtnActionTime >= mouseBtnActionsTreshhold {
|
||||||
|
lastRightBtnActionTime = now
|
||||||
|
g.ShootMissile(px, py)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -138,37 +176,44 @@ func (g *GameControls) OnMouseButtonDown(event d2input.MouseEvent) bool {
|
|||||||
py = float64(int(py*10)) / 10.0
|
py = float64(int(py*10)) / 10.0
|
||||||
|
|
||||||
if event.Button == d2input.MouseButtonLeft {
|
if event.Button == d2input.MouseButtonLeft {
|
||||||
|
lastLeftBtnActionTime = d2common.Now()
|
||||||
g.inputListener.OnPlayerMove(px, py)
|
g.inputListener.OnPlayerMove(px, py)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.Button == d2input.MouseButtonRight {
|
if event.Button == d2input.MouseButtonRight {
|
||||||
missile, err := d2mapentity.CreateMissile(
|
lastRightBtnActionTime = d2common.Now()
|
||||||
int(g.hero.AnimatedComposite.LocationX),
|
return g.ShootMissile(px, py)
|
||||||
int(g.hero.AnimatedComposite.LocationY),
|
|
||||||
d2datadict.Missiles[missileID],
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
rads := d2common.GetRadiansBetween(
|
|
||||||
g.hero.AnimatedComposite.LocationX,
|
|
||||||
g.hero.AnimatedComposite.LocationY,
|
|
||||||
px*5,
|
|
||||||
py*5,
|
|
||||||
)
|
|
||||||
missile.SetRadians(rads, func() {
|
|
||||||
g.mapEngine.RemoveEntity(missile)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.mapEngine.AddEntity(missile)
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) ShootMissile(px float64, py float64) bool {
|
||||||
|
missile, err := d2mapentity.CreateMissile(
|
||||||
|
int(g.hero.AnimatedComposite.LocationX),
|
||||||
|
int(g.hero.AnimatedComposite.LocationY),
|
||||||
|
d2datadict.Missiles[missileID],
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
rads := d2common.GetRadiansBetween(
|
||||||
|
g.hero.AnimatedComposite.LocationX,
|
||||||
|
g.hero.AnimatedComposite.LocationY,
|
||||||
|
px*5,
|
||||||
|
py*5,
|
||||||
|
)
|
||||||
|
|
||||||
|
missile.SetRadians(rads, func() {
|
||||||
|
g.mapEngine.RemoveEntity(missile)
|
||||||
|
})
|
||||||
|
|
||||||
|
g.mapEngine.AddEntity(missile)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GameControls) Load() {
|
func (g *GameControls) Load() {
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
|
animation, _ := d2asset.LoadAnimation(d2resource.GameGlobeOverlap, d2resource.PaletteSky)
|
||||||
g.globeSprite, _ = d2ui.LoadSprite(animation)
|
g.globeSprite, _ = d2ui.LoadSprite(animation)
|
||||||
@ -290,6 +335,24 @@ func (g *GameControls) Render(target d2render.Surface) {
|
|||||||
g.globeSprite.SetPosition(offset+8, height-8)
|
g.globeSprite.SetPosition(offset+8, height-8)
|
||||||
g.globeSprite.Render(target)
|
g.globeSprite.Render(target)
|
||||||
|
|
||||||
|
if g.isZoneTextShown {
|
||||||
|
g.zoneChangeText.SetPosition(width/2, height/4)
|
||||||
|
g.zoneChangeText.Render(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) SetZoneChangeText(text string) {
|
||||||
|
g.zoneChangeText.SetText(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) ShowZoneChangeText() {
|
||||||
|
g.isZoneTextShown = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameControls) HideZoneChangeTextAfter(delay float64) {
|
||||||
|
time.AfterFunc(time.Duration(delay)*time.Second, func() {
|
||||||
|
g.isZoneTextShown = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameControls) InEscapeMenu() bool {
|
func (g *GameControls) InEscapeMenu() bool {
|
||||||
|
@ -95,10 +95,11 @@ func (g *GameClient) OnPacketReceived(packet d2netpacket.NetPacket) error {
|
|||||||
|
|
||||||
regionType := tile.RegionType
|
regionType := tile.RegionType
|
||||||
if regionType == d2enum.RegionAct1Town {
|
if regionType == d2enum.RegionAct1Town {
|
||||||
player.AnimatedComposite.SetAnimationMode(d2enum.AnimationModePlayerTownNeutral.String())
|
player.SetIsInTown(true)
|
||||||
} else {
|
} else {
|
||||||
player.AnimatedComposite.SetAnimationMode(d2enum.AnimationModePlayerNeutral.String())
|
player.SetIsInTown(false)
|
||||||
}
|
}
|
||||||
|
player.AnimatedComposite.SetAnimationMode(player.GetAnimationMode().String())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user