From 1654fd7e903be1f711746a67e633bc1fee2e85cc Mon Sep 17 00:00:00 2001 From: dk Date: Fri, 17 Jul 2020 15:51:19 -0700 Subject: [PATCH] Removing lint errors in npc.go, mapstamp.go (#597) - made an enum for NPCActionType to get rid of magic numbers - moved the enum to d2enum - fixed lint errors in npc.go - fixed lint errors in mapstamp.go (because it was using npc.go) --- d2common/d2enum/npc_action_type.go | 14 +++++ d2core/d2map/d2mapentity/npc.go | 85 ++++++++++++++++++------------ d2core/d2map/d2mapstamp/stamp.go | 27 ++++++---- 3 files changed, 82 insertions(+), 44 deletions(-) create mode 100644 d2common/d2enum/npc_action_type.go diff --git a/d2common/d2enum/npc_action_type.go b/d2common/d2enum/npc_action_type.go new file mode 100644 index 00000000..82a564b3 --- /dev/null +++ b/d2common/d2enum/npc_action_type.go @@ -0,0 +1,14 @@ +package d2enum + +// NPCActionType determines composite mode animations for NPC's as they move around +type NPCActionType int + +// NPCAction types +// TODO: Figure out what 1-3 are for +const ( + NPCActionInvalid NPCActionType = iota + NPCAction1 + NPCAction2 + NPCAction3 + NPCActionSkill1 +) diff --git a/d2core/d2map/d2mapentity/npc.go b/d2core/d2map/d2mapentity/npc.go index 32ef6e02..62ad2bef 100644 --- a/d2core/d2map/d2mapentity/npc.go +++ b/d2core/d2map/d2mapentity/npc.go @@ -16,20 +16,28 @@ import ( // For example, Deckard Cain. type NPC struct { mapEntity + Paths []d2common.Path + name string composite *d2asset.Composite action int - HasPaths bool - Paths []d2common.Path path int - isDone bool repetitions int monstatRecord *d2datadict.MonStatsRecord monstatEx *d2datadict.MonStats2Record - name string + HasPaths bool + isDone bool } +const ( + magicOffsetX = 5 + magicOffsetScalarX = 8 + magicOffsetScalarY = 16 + minAnimationRepetitions = 3 + maxAnimationRepetitions = 5 +) + // CreateNPC creates a new NPC and returns a pointer to it. -func CreateNPC(x, y int, monstat *d2datadict.MonStatsRecord, direction int) *NPC { +func CreateNPC(x, y int, monstat *d2datadict.MonStatsRecord, direction int) (*NPC, error) { result := &NPC{ mapEntity: newMapEntity(x, y), HasPaths: false, @@ -47,8 +55,14 @@ func CreateNPC(x, y int, monstat *d2datadict.MonStatsRecord, direction int) *NPC d2resource.PaletteUnits) result.composite = composite - composite.SetMode(d2enum.MonsterAnimationModeNeutral, result.monstatEx.BaseWeaponClass) - composite.Equip(&equipment) + if err := composite.SetMode(d2enum.MonsterAnimationModeNeutral, + result.monstatEx.BaseWeaponClass); err != nil { + return nil, err + } + + if err := composite.Equip(&equipment); err != nil { + return nil, err + } result.SetSpeed(float64(monstat.SpeedBase)) result.mapEntity.directioner = result.rotate @@ -59,7 +73,7 @@ func CreateNPC(x, y int, monstat *d2datadict.MonStatsRecord, direction int) *NPC result.name = d2common.TranslateString(result.monstatRecord.NameString) } - return result + return result, nil } func selectEquip(slice []string) string { @@ -74,12 +88,15 @@ func selectEquip(slice []string) string { func (v *NPC) Render(target d2interface.Surface) { renderOffset := v.Position.RenderOffset() target.PushTranslation( - int((renderOffset.X()-renderOffset.Y())*16), - int(((renderOffset.X()+renderOffset.Y())*8)-5), + int((renderOffset.X()-renderOffset.Y())*magicOffsetScalarY), + int(((renderOffset.X()+renderOffset.Y())*magicOffsetScalarX)-magicOffsetX), ) defer target.Pop() - v.composite.Render(target) + + if v.composite.Render(target) != nil { + return + } } // Path returns the current part of the entity's path. @@ -110,7 +127,10 @@ func (v *NPC) SetPaths(paths []d2common.Path) { // single game tick. func (v *NPC) Advance(tickTime float64) { v.Step(tickTime) - v.composite.Advance(tickTime) + + if err := v.composite.Advance(tickTime); err != nil { + return + } if v.HasPaths && v.wait() { // If at the target, set target to the next path. @@ -133,26 +153,27 @@ func (v *NPC) wait() bool { } func (v *NPC) next() { + var newAnimationMode d2enum.MonsterAnimationMode + v.isDone = true - v.repetitions = 3 + rand.Intn(5) - newAnimationMode := d2enum.MonsterAnimationModeNeutral - // TODO: Figure out what 1-3 are for, 4 is correct. - switch v.action { - case 1: - newAnimationMode = d2enum.MonsterAnimationModeNeutral - case 2: - newAnimationMode = d2enum.MonsterAnimationModeNeutral - case 3: - newAnimationMode = d2enum.MonsterAnimationModeNeutral - case 4: + v.repetitions = minAnimationRepetitions + rand.Intn(maxAnimationRepetitions) + + switch d2enum.NPCActionType(v.action) { + case d2enum.NPCActionSkill1: newAnimationMode = d2enum.MonsterAnimationModeSkill1 v.repetitions = 0 + case d2enum.NPCActionInvalid, d2enum.NPCAction1, d2enum.NPCAction2, d2enum.NPCAction3: + newAnimationMode = d2enum.MonsterAnimationModeNeutral + v.repetitions = 0 default: + newAnimationMode = d2enum.MonsterAnimationModeNeutral v.repetitions = 0 } if v.composite.GetAnimationMode() != newAnimationMode.String() { - v.composite.SetMode(newAnimationMode, v.composite.GetWeaponClass()) + if err := v.composite.SetMode(newAnimationMode, v.composite.GetWeaponClass()); err != nil { + return + } } } @@ -166,7 +187,9 @@ func (v *NPC) rotate(direction int) { } if newMode.String() != v.composite.GetAnimationMode() { - v.composite.SetMode(newMode, v.composite.GetWeaponClass()) + if err := v.composite.SetMode(newMode, v.composite.GetWeaponClass()); err != nil { + return + } } if v.composite.GetDirection() != direction { @@ -175,16 +198,12 @@ func (v *NPC) rotate(direction int) { } // Selectable returns true if the object can be highlighted/selected. -func (m *NPC) Selectable() bool { +func (v *NPC) Selectable() bool { // is there something handy that determines selectable npc's? - if m.name != "" { - return true - } - - return false + return v.name != "" } // Name returns the NPC's in-game name (e.g. "Deckard Cain") or an empty string if it does not have a name. -func (m *NPC) Name() string { - return m.name +func (v *NPC) Name() string { + return v.name } diff --git a/d2core/d2map/d2mapstamp/stamp.go b/d2core/d2map/d2mapstamp/stamp.go index 6cfbc119..b91b4fe4 100644 --- a/d2core/d2map/d2mapstamp/stamp.go +++ b/d2core/d2map/d2mapstamp/stamp.go @@ -27,14 +27,14 @@ type Stamp struct { } // LoadStamp loads the Stamp data from file. -func LoadStamp(levelType d2enum.RegionIdType, levelPreset int, fileIndex int) *Stamp { +func LoadStamp(levelType d2enum.RegionIdType, levelPreset, fileIndex int) *Stamp { stamp := &Stamp{ levelType: d2datadict.LevelTypes[levelType], levelPreset: d2datadict.LevelPresets[levelPreset], } - for _, levelTypeDt1 := range stamp.levelType.Files { - if len(levelTypeDt1) != 0 && levelTypeDt1 != "" && levelTypeDt1 != "0" { + for _, levelTypeDt1 := range &stamp.levelType.Files { + if levelTypeDt1 != "" && levelTypeDt1 != "0" { fileData, err := d2asset.LoadFile("/data/global/tiles/" + levelTypeDt1) if err != nil { panic(err) @@ -49,7 +49,7 @@ func LoadStamp(levelType d2enum.RegionIdType, levelPreset int, fileIndex int) *S var levelFilesToPick []string for _, fileRecord := range stamp.levelPreset.Files { - if len(fileRecord) != 0 && fileRecord != "" && fileRecord != "0" { + if fileRecord != "" && fileRecord != "0" { levelFilesToPick = append(levelFilesToPick, fileRecord) } } @@ -84,7 +84,7 @@ func LoadStamp(levelType d2enum.RegionIdType, levelPreset int, fileIndex int) *S // Size returns the size of the stamp in tiles. func (mr *Stamp) Size() d2common.Size { - return d2common.Size{int(mr.ds1.Width), int(mr.ds1.Height)} + return d2common.Size{Width: int(mr.ds1.Width), Height: int(mr.ds1.Height)} } // LevelPreset returns the level preset ID. @@ -108,10 +108,11 @@ func (mr *Stamp) Tile(x, y int) *d2ds1.TileRecord { } // TileData returns the tile data for the tile with given style, sequence and type. -func (mr *Stamp) TileData(style int32, sequence int32, tileType d2enum.TileType) *d2dt1.Tile { - for _, tile := range mr.tiles { +func (mr *Stamp) TileData(style, sequence int32, tileType d2enum.TileType) *d2dt1.Tile { + for idx := range mr.tiles { + tile := &mr.tiles[idx] if tile.Style == style && tile.Sequence == sequence && tile.Type == int32(tileType) { - return &tile + return tile } } @@ -129,9 +130,13 @@ func (mr *Stamp) Entities(tileOffsetX, tileOffsetY int) []d2interface.MapEntity // (See monpreset and monplace txts for reference) if monstat != nil { // Temorary use of Lookup. - npc := d2mapentity.CreateNPC((tileOffsetX*5)+object.X, (tileOffsetY*5)+object.Y, monstat, 0) - npc.SetPaths(convertPaths(tileOffsetX, tileOffsetY, object.Paths)) - entities = append(entities, npc) + npcX, npcY := (tileOffsetX*5)+object.X, (tileOffsetY*5)+object.Y + npc, err := d2mapentity.CreateNPC(npcX, npcY, monstat, 0) + + if err == nil { + npc.SetPaths(convertPaths(tileOffsetX, tileOffsetY, object.Paths)) + entities = append(entities, npc) + } } }