mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-12 12:26:31 -05:00
D2mapengine remove entity, minor edits (#694)
* implement entity removal * add rgba color func, fix some lint errors in d2map * bugfix for map entity tests
This commit is contained in:
parent
0a6915a040
commit
8b2b991b12
@ -4,6 +4,7 @@ import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
||||
|
||||
// MapEntity is something that can be positioned on and rendered on the game map
|
||||
type MapEntity interface {
|
||||
ID() string
|
||||
Render(target Surface)
|
||||
Advance(tickTime float64)
|
||||
GetPosition() d2vector.Position
|
||||
|
28
d2common/rgba_color.go
Normal file
28
d2common/rgba_color.go
Normal file
@ -0,0 +1,28 @@
|
||||
package d2common
|
||||
|
||||
import "image/color"
|
||||
|
||||
func Color(rgba uint32) color.RGBA {
|
||||
result := color.RGBA{}
|
||||
a, b, g, r := 0, 1, 2, 3
|
||||
byteWidth := 8
|
||||
byteMask := 0xff
|
||||
|
||||
for idx := 0; idx < 4; idx++ {
|
||||
shift := idx * byteWidth
|
||||
component := uint8(rgba>>shift) & uint8(byteMask)
|
||||
|
||||
switch idx {
|
||||
case a:
|
||||
result.A = component
|
||||
case b:
|
||||
result.B = component
|
||||
case g:
|
||||
result.G = component
|
||||
case r:
|
||||
result.R = component
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
@ -20,8 +20,8 @@ import (
|
||||
|
||||
// MapEngine loads the tiles which make up the isometric map and the entities
|
||||
type MapEngine struct {
|
||||
seed int64 // The map seed
|
||||
entities []d2interface.MapEntity // Entities on the map
|
||||
seed int64 // The map seed
|
||||
entities map[string]d2interface.MapEntity // Entities on the map
|
||||
tiles []MapTile
|
||||
size d2common.Size // Size of the map, in tiles
|
||||
levelType d2datadict.LevelTypeRecord // Level type of this map
|
||||
@ -44,7 +44,7 @@ func (m *MapEngine) GetStartingPosition() (x, y int) {
|
||||
|
||||
// ResetMap clears all map and entity data and reloads it from the cached files.
|
||||
func (m *MapEngine) ResetMap(levelType d2enum.RegionIdType, width, height int) {
|
||||
m.entities = make([]d2interface.MapEntity, 0)
|
||||
m.entities = make(map[string]d2interface.MapEntity)
|
||||
m.levelType = d2datadict.LevelTypes[levelType]
|
||||
m.size = d2common.Size{Width: width, Height: height}
|
||||
m.tiles = make([]MapTile, width*height)
|
||||
@ -155,7 +155,7 @@ func (m *MapEngine) PlaceStamp(stamp *d2mapstamp.Stamp, tileOffsetX, tileOffsetY
|
||||
// Copy over the map tile data
|
||||
for y := 0; y < stampH; y++ {
|
||||
for x := 0; x < stampW; x++ {
|
||||
targetTileIndex := m.tileCoordinateToIndex((x + xMin), (y + yMin))
|
||||
targetTileIndex := m.tileCoordinateToIndex(x+xMin, y+yMin)
|
||||
stampTile := *stamp.Tile(x, y)
|
||||
m.tiles[targetTileIndex].RegionType = stamp.RegionID()
|
||||
m.tiles[targetTileIndex].Components = stampTile
|
||||
@ -164,7 +164,11 @@ func (m *MapEngine) PlaceStamp(stamp *d2mapstamp.Stamp, tileOffsetX, tileOffsetY
|
||||
}
|
||||
|
||||
// Copy over the entities
|
||||
m.entities = append(m.entities, stamp.Entities(tileOffsetX, tileOffsetY)...)
|
||||
stampEntities := stamp.Entities(tileOffsetX, tileOffsetY)
|
||||
for idx := range stampEntities {
|
||||
e := stampEntities[idx]
|
||||
m.entities[e.ID()] = e
|
||||
}
|
||||
}
|
||||
|
||||
// converts x,y tile coordinate into index in MapEngine.tiles
|
||||
@ -172,7 +176,7 @@ func (m *MapEngine) tileCoordinateToIndex(x, y int) int {
|
||||
return x + (y * m.size.Width)
|
||||
}
|
||||
|
||||
// converts tile index from MapEngine.tiles to x,y coordinate
|
||||
// tileIndexToCoordinate converts tile index from MapEngine.tiles to x,y coordinate
|
||||
func (m *MapEngine) tileIndexToCoordinate(index int) (x, y int) {
|
||||
return index % m.size.Width, index / m.size.Width
|
||||
}
|
||||
@ -196,8 +200,8 @@ func (m *MapEngine) TileAt(tileX, tileY int) *MapTile {
|
||||
}
|
||||
|
||||
// Entities returns a pointer a slice of all map entities.
|
||||
func (m *MapEngine) Entities() *[]d2interface.MapEntity {
|
||||
return &m.entities
|
||||
func (m *MapEngine) Entities() map[string]d2interface.MapEntity {
|
||||
return m.entities
|
||||
}
|
||||
|
||||
// Seed returns the map generation seed.
|
||||
@ -207,15 +211,16 @@ func (m *MapEngine) Seed() int64 {
|
||||
|
||||
// AddEntity adds an entity to a slice containing all entities.
|
||||
func (m *MapEngine) AddEntity(entity d2interface.MapEntity) {
|
||||
m.entities = append(m.entities, entity)
|
||||
m.entities[entity.ID()] = entity
|
||||
}
|
||||
|
||||
// RemoveEntity is not currently implemented.
|
||||
// RemoveEntity removes an entity from the map engine
|
||||
func (m *MapEngine) RemoveEntity(entity d2interface.MapEntity) {
|
||||
if entity == nil {
|
||||
return
|
||||
}
|
||||
// m.entities.Remove(entity)
|
||||
|
||||
delete(m.entities, entity.ID())
|
||||
}
|
||||
|
||||
// GetTiles returns a slice of all tiles matching the given style,
|
||||
@ -264,8 +269,8 @@ func (m *MapEngine) GetCenterPosition() (x, y float64) {
|
||||
// Advance calls the Advance() method for all entities,
|
||||
// processing a single tick.
|
||||
func (m *MapEngine) Advance(tickTime float64) {
|
||||
for idx := range m.entities {
|
||||
m.entities[idx].Advance(tickTime)
|
||||
for ID := range m.entities {
|
||||
m.entities[ID].Advance(tickTime)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package d2mapentity
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -50,7 +49,6 @@ func NewPlayer(id, name string, x, y, direction int, heroType d2enum.Hero,
|
||||
stats.Stamina = stats.MaxStamina
|
||||
|
||||
result := &Player{
|
||||
ID: id,
|
||||
mapEntity: newMapEntity(x, y),
|
||||
composite: composite,
|
||||
Equipment: equipment,
|
||||
@ -62,6 +60,8 @@ func NewPlayer(id, name string, x, y, direction int, heroType d2enum.Hero,
|
||||
isInTown: true,
|
||||
isRunning: true,
|
||||
}
|
||||
|
||||
result.mapEntity.uuid = id
|
||||
result.SetSpeed(baseRunSpeed)
|
||||
result.mapEntity.directioner = result.rotate
|
||||
err = composite.SetMode(d2enum.PlayerAnimationModeTownNeutral, equipment.RightHand.GetWeaponClass())
|
||||
|
@ -19,6 +19,11 @@ type Item struct {
|
||||
Item *diablo2item.Item
|
||||
}
|
||||
|
||||
// ID returns the item uuid
|
||||
func (i *Item) ID() string {
|
||||
return i.AnimatedEntity.uuid
|
||||
}
|
||||
|
||||
// GetPosition returns the item position vector
|
||||
func (i *Item) GetPosition() d2vector.Position {
|
||||
return i.AnimatedEntity.Position
|
||||
|
@ -1,6 +1,8 @@
|
||||
package d2mapentity
|
||||
|
||||
import (
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
||||
)
|
||||
|
||||
@ -10,6 +12,7 @@ const (
|
||||
|
||||
// mapEntity represents an entity on the map that can be animated
|
||||
type mapEntity struct {
|
||||
uuid string
|
||||
Position d2vector.Position
|
||||
Target d2vector.Position
|
||||
velocity d2vector.Vector
|
||||
@ -29,6 +32,7 @@ func newMapEntity(x, y int) mapEntity {
|
||||
pos := d2vector.NewPosition(float64(x), float64(y))
|
||||
|
||||
return mapEntity{
|
||||
uuid: uuid.NewV4().String(),
|
||||
Position: pos,
|
||||
Target: pos,
|
||||
velocity: *d2vector.VectorZero(),
|
||||
|
@ -14,6 +14,11 @@ type Missile struct {
|
||||
record *d2datadict.MissileRecord
|
||||
}
|
||||
|
||||
// ID returns the missile uuid
|
||||
func (m *Missile) ID() string {
|
||||
return m.AnimatedEntity.uuid
|
||||
}
|
||||
|
||||
// GetPosition returns the position of the missile
|
||||
func (m *Missile) GetPosition() d2vector.Position {
|
||||
return m.AnimatedEntity.Position
|
||||
|
@ -43,6 +43,11 @@ func selectEquip(slice []string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// ID returns the NPC uuid
|
||||
func (v *NPC) ID() string {
|
||||
return v.mapEntity.uuid
|
||||
}
|
||||
|
||||
// Render renders this entity's animated composite.
|
||||
func (v *NPC) Render(target d2interface.Surface) {
|
||||
renderOffset := v.Position.RenderOffset()
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
// Player is the player character entity.
|
||||
type Player struct {
|
||||
mapEntity
|
||||
ID string
|
||||
name string
|
||||
animationMode string
|
||||
composite *d2asset.Composite
|
||||
@ -35,6 +34,11 @@ type Player struct {
|
||||
const baseWalkSpeed = 6.0
|
||||
const baseRunSpeed = 9.0
|
||||
|
||||
// ID returns the Player uuid
|
||||
func (p *Player) ID() string {
|
||||
return p.mapEntity.uuid
|
||||
}
|
||||
|
||||
// SetIsInTown sets a flag indicating that the player is in town.
|
||||
func (p *Player) SetIsInTown(isInTown bool) {
|
||||
p.isInTown = isInTown
|
||||
@ -86,7 +90,7 @@ func (p *Player) Advance(tickTime float64) {
|
||||
}
|
||||
|
||||
if err := p.composite.Advance(tickTime); err != nil {
|
||||
fmt.Printf("failed to advance composite animation of player: %s, err: %v\n", p.ID, err)
|
||||
fmt.Printf("failed to advance composite animation of player: %s, err: %v\n", p.ID(), err)
|
||||
}
|
||||
|
||||
if p.lastPathSize != len(p.path) {
|
||||
@ -109,7 +113,7 @@ func (p *Player) Render(target d2interface.Surface) {
|
||||
defer target.Pop()
|
||||
|
||||
if err := p.composite.Render(target); err != nil {
|
||||
fmt.Printf("failed to render the composite of player: %s, err: %v\n", p.ID, err)
|
||||
fmt.Printf("failed to render the composite of player: %s, err: %v\n", p.ID(), err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +177,8 @@ func (p *Player) IsCasting() bool {
|
||||
func (p *Player) SetCasting() {
|
||||
p.isCasting = true
|
||||
if err := p.SetAnimationMode(d2enum.PlayerAnimationModeCast); err != nil {
|
||||
fmt.Printf("failed to set animationMode of player: %s to: %d, err: %v\n", p.ID, d2enum.PlayerAnimationModeCast, err)
|
||||
fmtStr := "failed to set animationMode of player: %s to: %d, err: %v\n"
|
||||
fmt.Printf(fmtStr, p.ID(), d2enum.PlayerAnimationModeCast, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2math/d2vector"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -19,6 +20,31 @@ import (
|
||||
|
||||
const (
|
||||
screenMiddleX = 400
|
||||
two = 2
|
||||
|
||||
dbgOffsetXY = 40
|
||||
dbgBoxWidth = 220
|
||||
dbgBoxHeight = 60
|
||||
dbgBoxPadding = 10
|
||||
|
||||
dbgCollisionSize = 5
|
||||
dbgCollisionOffsetX = -3
|
||||
dbgCollisionOffsetY = 4
|
||||
|
||||
whiteHalfOpacity = 0xffffff7f
|
||||
blackQuarterOpacity = 0x00000040
|
||||
lightGreenFullOpacity = 0x40ff00ff
|
||||
magentaFullOpacity = 0xff00ffff
|
||||
yellowFullOpacity = 0xffff00ff
|
||||
lightBlueQuarterOpacity = 0x5050ff32
|
||||
whiteQuarterOpacity = 0xffffff64
|
||||
redQuarterOpacity = 0x74000064
|
||||
|
||||
subtilesPerTile = 5
|
||||
orthoSubTileWidth = 16
|
||||
orthoSubTileHeight = 8
|
||||
orthoTileWidth = subtilesPerTile * orthoSubTileWidth
|
||||
orthoTileHeight = subtilesPerTile * orthoSubTileHeight
|
||||
)
|
||||
|
||||
// MapRenderer manages the game viewport and Camera. It requests tile and entity data from MapEngine and renders it.
|
||||
@ -172,7 +198,7 @@ func (mr *MapRenderer) renderPass2(target d2interface.Surface, startX, startY, e
|
||||
mr.viewport.PushTranslationWorld(float64(tileX), float64(tileY))
|
||||
|
||||
// TODO: Do not loop over every entity every frame
|
||||
for _, mapEntity := range *mr.mapEngine.Entities() {
|
||||
for _, mapEntity := range mr.mapEngine.Entities() {
|
||||
pos := mapEntity.GetPosition()
|
||||
vec := pos.World()
|
||||
entityX, entityY := vec.X(), vec.Y()
|
||||
@ -204,7 +230,7 @@ func (mr *MapRenderer) renderPass3(target d2interface.Surface, startX, startY, e
|
||||
mr.renderTilePass2(tile, target)
|
||||
|
||||
// TODO: Do not loop over every entity every frame
|
||||
for _, mapEntity := range *mr.mapEngine.Entities() {
|
||||
for _, mapEntity := range mr.mapEngine.Entities() {
|
||||
pos := mapEntity.GetPosition()
|
||||
vec := pos.World()
|
||||
entityX, entityY := vec.X(), vec.Y()
|
||||
@ -327,9 +353,10 @@ func (mr *MapRenderer) renderShadow(tile d2ds1.FloorShadowRecord, target d2inter
|
||||
defer mr.viewport.PushTranslationOrtho(-80, float64(tile.YAdjust)).PopTranslation()
|
||||
|
||||
target.PushTranslation(mr.viewport.GetTranslationScreen())
|
||||
target.PushColor(color.RGBA{R: 255, G: 255, B: 255, A: 160}) //nolint:gomnd // Not a magic number...
|
||||
defer target.Pop()
|
||||
|
||||
defer target.PopN(2)
|
||||
target.PushColor(color.RGBA{R: 255, G: 255, B: 255, A: 160}) //nolint:gomnd // Not a magic number...
|
||||
defer target.Pop()
|
||||
|
||||
if err := target.Render(img); err != nil {
|
||||
fmt.Printf("failed to render the shadow, err: %v\n", err)
|
||||
@ -346,26 +373,27 @@ func (mr *MapRenderer) renderMapDebug(mapDebugVisLevel int, target d2interface.S
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:funlen // doesn't make sense to split this function
|
||||
func (mr *MapRenderer) renderEntityDebug(target d2interface.Surface) {
|
||||
entities := *mr.mapEngine.Entities()
|
||||
entities := mr.mapEngine.Entities()
|
||||
|
||||
for idx := range entities {
|
||||
e := entities[idx]
|
||||
pos := e.GetPosition()
|
||||
world := pos
|
||||
x, y := world.X()/5, world.Y()/5
|
||||
x, y := world.X()/subtilesPerTile, world.Y()/subtilesPerTile
|
||||
velocity := e.GetVelocity()
|
||||
velocity = *velocity.Clone()
|
||||
vx, vy := mr.viewport.WorldToOrtho(velocity.X(), velocity.Y())
|
||||
screenX, screenY := mr.viewport.WorldToScreen(x, y)
|
||||
|
||||
offX, offY := 40, -40
|
||||
offX, offY := dbgOffsetXY, -dbgOffsetXY
|
||||
|
||||
entScreenXf, entScreenYf := mr.WorldToScreenF(e.GetPositionF())
|
||||
entScreenX := int(math.Floor(entScreenXf))
|
||||
entScreenY := int(math.Floor(entScreenYf))
|
||||
entityWidth, entityHeight := e.GetSize()
|
||||
halfWidth, halfHeight := entityWidth/2, entityHeight/2
|
||||
halfWidth, halfHeight := entityWidth/two, entityHeight/two
|
||||
l, r := entScreenX-halfWidth, entScreenX+halfWidth
|
||||
t, b := entScreenY-halfHeight, entScreenY+halfHeight
|
||||
mx, my := mr.renderer.GetCursorPos()
|
||||
@ -373,8 +401,8 @@ func (mr *MapRenderer) renderEntityDebug(target d2interface.Surface) {
|
||||
yWithin := (t <= my) && (b >= my)
|
||||
within := xWithin && yWithin
|
||||
|
||||
boxLineColor := color.RGBA{255, 0, 255, 128}
|
||||
boxHoverColor := color.RGBA{255, 255, 0, 128}
|
||||
boxLineColor := d2common.Color(magentaFullOpacity)
|
||||
boxHoverColor := d2common.Color(yellowFullOpacity)
|
||||
|
||||
boxColor := boxLineColor
|
||||
|
||||
@ -382,30 +410,39 @@ func (mr *MapRenderer) renderEntityDebug(target d2interface.Surface) {
|
||||
boxColor = boxHoverColor
|
||||
}
|
||||
|
||||
stack := 0
|
||||
// box
|
||||
mr.viewport.PushTranslationWorld(x, y)
|
||||
|
||||
target.PushTranslation(screenX, screenY)
|
||||
stack++
|
||||
|
||||
target.PushTranslation(-halfWidth, -halfHeight)
|
||||
stack++
|
||||
|
||||
target.DrawLine(0, entityHeight, boxColor)
|
||||
target.DrawLine(entityWidth, 0, boxColor)
|
||||
|
||||
target.PushTranslation(entityWidth, entityHeight)
|
||||
stack++
|
||||
|
||||
target.DrawLine(-entityWidth, 0, boxColor)
|
||||
target.DrawLine(0, -entityHeight, boxColor)
|
||||
target.PopN(3)
|
||||
target.PopN(stack)
|
||||
mr.viewport.PopTranslation()
|
||||
|
||||
// hover
|
||||
if within {
|
||||
mr.viewport.PushTranslationWorld(x, y)
|
||||
target.PushTranslation(screenX, screenY)
|
||||
target.DrawLine(offX, offY, color.RGBA{255, 255, 255, 128})
|
||||
target.PushTranslation(offX+10, offY-20)
|
||||
target.PushTranslation(-10, -10)
|
||||
target.DrawRect(200, 50, color.RGBA{0, 0, 0, 64})
|
||||
target.DrawLine(offX, offY, d2common.Color(whiteHalfOpacity))
|
||||
target.PushTranslation(offX+dbgBoxPadding, offY-dbgBoxPadding*two)
|
||||
target.PushTranslation(-dbgOffsetXY, -dbgOffsetXY)
|
||||
target.DrawRect(dbgBoxWidth, dbgBoxHeight, d2common.Color(blackQuarterOpacity))
|
||||
target.Pop()
|
||||
target.DrawTextf("World (%.2f, %.2f)\nVelocity (%.2f, %.2f)", x, y, vx, vy)
|
||||
target.Pop()
|
||||
target.DrawLine(int(vx), int(vy), color.RGBA{64, 255, 0, 255})
|
||||
target.DrawLine(int(vx), int(vy), d2common.Color(lightGreenFullOpacity))
|
||||
target.Pop()
|
||||
mr.viewport.PopTranslation()
|
||||
}
|
||||
@ -423,9 +460,9 @@ func (mr *MapRenderer) WorldToScreenF(x, y float64) (screenX, screenY float64) {
|
||||
}
|
||||
|
||||
func (mr *MapRenderer) renderTileDebug(ax, ay, debugVisLevel int, target d2interface.Surface) {
|
||||
subTileColor := color.RGBA{R: 80, G: 80, B: 255, A: 50}
|
||||
tileColor := color.RGBA{R: 255, G: 255, B: 255, A: 100}
|
||||
tileCollisionColor := color.RGBA{R: 128, G: 0, B: 0, A: 100}
|
||||
subTileColor := d2common.Color(lightBlueQuarterOpacity)
|
||||
tileColor := d2common.Color(whiteQuarterOpacity)
|
||||
tileCollisionColor := d2common.Color(redQuarterOpacity)
|
||||
|
||||
screenX1, screenY1 := mr.viewport.WorldToScreen(float64(ax), float64(ay))
|
||||
screenX2, screenY2 := mr.viewport.WorldToScreen(float64(ax+1), float64(ay))
|
||||
@ -442,15 +479,15 @@ func (mr *MapRenderer) renderTileDebug(ax, ay, debugVisLevel int, target d2inter
|
||||
|
||||
if debugVisLevel > 1 {
|
||||
for i := 1; i <= 4; i++ {
|
||||
x2 := i * 16
|
||||
y2 := i * 8
|
||||
x2 := i * orthoSubTileWidth
|
||||
y2 := i * orthoSubTileHeight
|
||||
|
||||
target.PushTranslation(-x2, y2)
|
||||
target.DrawLine(80, 40, subTileColor)
|
||||
target.DrawLine(orthoTileWidth, orthoTileHeight, subTileColor)
|
||||
target.Pop()
|
||||
|
||||
target.PushTranslation(x2, y2)
|
||||
target.DrawLine(-80, 40, subTileColor)
|
||||
target.DrawLine(-orthoTileWidth, orthoTileHeight, subTileColor)
|
||||
target.Pop()
|
||||
}
|
||||
|
||||
@ -458,7 +495,7 @@ func (mr *MapRenderer) renderTileDebug(ax, ay, debugVisLevel int, target d2inter
|
||||
|
||||
for i, wall := range tile.Components.Walls {
|
||||
if wall.Type.Special() {
|
||||
target.PushTranslation(-20, 10+(i+1)*14)
|
||||
target.PushTranslation(-20, 10+(i+1)*14) // what are these magic numbers??
|
||||
target.DrawTextf("s: %v-%v", wall.Style, wall.Sequence)
|
||||
target.Pop()
|
||||
}
|
||||
@ -466,14 +503,14 @@ func (mr *MapRenderer) renderTileDebug(ax, ay, debugVisLevel int, target d2inter
|
||||
|
||||
for yy := 0; yy < 5; yy++ {
|
||||
for xx := 0; xx < 5; xx++ {
|
||||
isoX := (xx - yy) * 16
|
||||
isoY := (xx + yy) * 8
|
||||
isoX := (xx - yy) * orthoSubTileWidth
|
||||
isoY := (xx + yy) * orthoSubTileHeight
|
||||
|
||||
blocked := tile.GetSubTileFlags(xx, yy).BlockWalk
|
||||
|
||||
if blocked {
|
||||
target.PushTranslation(isoX-3, isoY+4)
|
||||
target.DrawRect(5, 5, tileCollisionColor)
|
||||
target.PushTranslation(isoX+dbgCollisionOffsetX, isoY+dbgCollisionOffsetY)
|
||||
target.DrawRect(dbgCollisionSize, dbgCollisionSize, tileCollisionColor)
|
||||
target.Pop()
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ package d2object
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
@ -15,6 +17,7 @@ import (
|
||||
|
||||
// Object represents a composite of animations that can be projected onto the map.
|
||||
type Object struct {
|
||||
uuid string
|
||||
Position d2vector.Position
|
||||
composite *d2asset.Composite
|
||||
highlight bool
|
||||
@ -28,6 +31,7 @@ type Object struct {
|
||||
func CreateObject(x, y int, objectRec *d2datadict.ObjectRecord, palettePath string) (*Object, error) {
|
||||
locX, locY := float64(x), float64(y)
|
||||
entity := &Object{
|
||||
uuid: uuid.NewV4().String(),
|
||||
objectRecord: objectRec,
|
||||
Position: d2vector.NewPosition(locX, locY),
|
||||
name: d2common.TranslateString(objectRec.Name),
|
||||
@ -84,6 +88,11 @@ func (ob *Object) setMode(animationMode d2enum.ObjectAnimationMode, direction in
|
||||
return err
|
||||
}
|
||||
|
||||
// ID returns the object uuid
|
||||
func (ob *Object) ID() string {
|
||||
return ob.uuid
|
||||
}
|
||||
|
||||
// Highlight sets the entity highlighted flag to true.
|
||||
func (ob *Object) Highlight() {
|
||||
ob.highlight = true
|
||||
|
@ -56,7 +56,7 @@ func CreateGame(
|
||||
// find the local player and its initial location
|
||||
var startX, startY float64
|
||||
for _, player := range gameClient.Players {
|
||||
if player.ID != gameClient.PlayerID {
|
||||
if player.ID() != gameClient.PlayerID {
|
||||
continue
|
||||
}
|
||||
worldPosition := player.Position.World()
|
||||
@ -237,7 +237,7 @@ func (v *Game) Advance(elapsed float64) error {
|
||||
|
||||
func (v *Game) bindGameControls() error {
|
||||
for _, player := range v.gameClient.Players {
|
||||
if player.ID != v.gameClient.PlayerID {
|
||||
if player.ID() != v.gameClient.PlayerID {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ func (v *Game) bindGameControls() error {
|
||||
v.gameControls.Load()
|
||||
|
||||
if err := v.inputManager.BindHandler(v.gameControls); err != nil {
|
||||
fmt.Printf(bindControlsErrStr, player.ID)
|
||||
fmt.Printf(bindControlsErrStr, player.ID())
|
||||
}
|
||||
|
||||
break
|
||||
|
@ -421,8 +421,8 @@ func (g *GameControls) isInActiveMenusRect(px int, py int) bool {
|
||||
|
||||
// TODO: consider caching the panels to single image that is reused.
|
||||
func (g *GameControls) Render(target d2interface.Surface) error {
|
||||
for entityIdx := range *g.mapEngine.Entities() {
|
||||
entity := (*g.mapEngine.Entities())[entityIdx]
|
||||
for entityIdx := range g.mapEngine.Entities() {
|
||||
entity := (g.mapEngine.Entities())[entityIdx]
|
||||
if !entity.Selectable() {
|
||||
continue
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ func (g *GameClient) handleAddPlayerPacket(packet d2netpacket.NetPacket) error {
|
||||
newPlayer := d2mapentity.NewPlayer(player.ID, player.Name, player.X, player.Y, 0,
|
||||
player.HeroType, player.Stats, &player.Equipment)
|
||||
|
||||
g.Players[newPlayer.ID] = newPlayer
|
||||
g.Players[newPlayer.ID()] = newPlayer
|
||||
g.MapEngine.AddEntity(newPlayer)
|
||||
|
||||
return nil
|
||||
@ -214,7 +214,8 @@ func (g *GameClient) handleMovePlayerPacket(packet d2netpacket.NetPacket) error
|
||||
err := player.SetAnimationMode(player.GetAnimationMode())
|
||||
|
||||
if err != nil {
|
||||
log.Printf("GameClient: error setting animation mode for player %s: %s", player.ID, err)
|
||||
fmtStr := "GameClient: error setting animation mode for player %s: %s"
|
||||
log.Printf(fmtStr, player.ID(), err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user