From 16a82442bbafe3517503f3558972a40dc43efb18 Mon Sep 17 00:00:00 2001 From: gravestench Date: Fri, 23 Oct 2020 14:00:51 +0100 Subject: [PATCH] removed a bunch of magic number lint errors (#785) * removed magic numbers from d2ui/button.go * removed a bunch of magic number lint errors --- d2core/d2item/diablo2item/item.go | 8 +- d2core/d2map/d2mapengine/map_tile.go | 12 +- d2core/d2map/d2mapengine/pathfind.go | 2 +- d2core/d2map/d2mapentity/factory.go | 6 +- d2core/d2map/d2mapentity/object.go | 4 +- d2core/d2map/d2mapentity/player.go | 21 ++- d2core/d2map/d2mapgen/act1_overworld.go | 176 +++++++++++++---------- d2core/d2map/d2maprenderer/renderer.go | 2 +- d2core/d2map/d2maprenderer/tile_cache.go | 23 ++- d2core/d2map/d2mapstamp/factory.go | 4 + d2core/d2ui/button.go | 39 ++--- d2game/d2player/escape_menu.go | 6 +- d2game/d2player/help/help.go | 120 ++++++++++------ 13 files changed, 264 insertions(+), 159 deletions(-) diff --git a/d2core/d2item/diablo2item/item.go b/d2core/d2item/diablo2item/item.go index 9edf1978..75643f24 100644 --- a/d2core/d2item/diablo2item/item.go +++ b/d2core/d2item/diablo2item/item.go @@ -44,7 +44,10 @@ const ( rareJewelAffixMax = 4 ) -const maxAffixesOnMagicItem = 2 +const ( + maxAffixesOnMagicItem = 2 + sidesOnACoin = 2 // for random coin flip +) // static check to ensure Item implements Item var _ d2item.Item = &Item{} @@ -362,7 +365,8 @@ func (i *Item) pickRandomAffixes(max, totalMax int, for numPicks := 0; numPicks < max; numPicks++ { matches := i.factory.FindMatchingAffixes(i.CommonRecord(), affixMap) - if rollPrefix := i.rand.Intn(2); rollPrefix > 0 { + // flip a coin for whether to get an affix on this pick + if coinToss := i.rand.Intn(sidesOnACoin) > 0; coinToss { affixCount := len(i.PrefixRecords()) + len(i.SuffixRecords()) if len(i.PrefixRecords()) > max || affixCount > totalMax { break diff --git a/d2core/d2map/d2mapengine/map_tile.go b/d2core/d2map/d2mapengine/map_tile.go index dd7bb800..f43f66db 100644 --- a/d2core/d2map/d2mapengine/map_tile.go +++ b/d2core/d2map/d2mapengine/map_tile.go @@ -86,9 +86,15 @@ func getRandomTile(tiles []d2dt1.Tile, x, y int, seed int64) byte { tileSeed = uint64(seed) + uint64(x) tileSeed *= uint64(y) - tileSeed ^= tileSeed << 13 - tileSeed ^= tileSeed >> 17 - tileSeed ^= tileSeed << 5 + const ( + xorshiftA = 13 + xorshiftB = 17 + xorshiftC = 5 + ) + + tileSeed ^= tileSeed << xorshiftA + tileSeed ^= tileSeed >> xorshiftB + tileSeed ^= tileSeed << xorshiftC weightSum := 0 diff --git a/d2core/d2map/d2mapengine/pathfind.go b/d2core/d2map/d2mapengine/pathfind.go index 55ac6855..78dd99b7 100644 --- a/d2core/d2map/d2mapengine/pathfind.go +++ b/d2core/d2map/d2mapengine/pathfind.go @@ -27,7 +27,7 @@ func (m *MapEngine) checkLos(start, end d2vector.Position) (bool, d2vector.Posit if N == 0 { divN = 0.0 } else { - divN = 1.0 / N + divN = 1.0 / N // nolint:gomnd // we're just taking inverse... } xstep := dx * divN diff --git a/d2core/d2map/d2mapentity/factory.go b/d2core/d2map/d2mapentity/factory.go index 81b6a4fc..a723be97 100644 --- a/d2core/d2map/d2mapentity/factory.go +++ b/d2core/d2map/d2mapentity/factory.go @@ -17,6 +17,10 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2core/d2records" ) +const ( + subtilesPerTile = 5 +) + // NewMapEntityFactory creates a MapEntityFactory instance with the given asset manager func NewMapEntityFactory(asset *d2asset.AssetManager) (*MapEntityFactory, error) { itemFactory, err := diablo2item.NewItemFactory(asset) @@ -166,7 +170,7 @@ func (f *MapEntityFactory) NewItem(x, y int, codes ...string) (*Item, error) { animation.PlayForward() animation.SetPlayLoop(false) - entity := NewAnimatedEntity(x*5, y*5, animation) + entity := NewAnimatedEntity(x*subtilesPerTile, y*subtilesPerTile, animation) result := &Item{ AnimatedEntity: entity, diff --git a/d2core/d2map/d2mapentity/object.go b/d2core/d2map/d2mapentity/object.go index 5f99ad6f..97870fb2 100644 --- a/d2core/d2map/d2mapentity/object.go +++ b/d2core/d2map/d2mapentity/object.go @@ -79,8 +79,8 @@ func (ob *Object) Selectable() bool { func (ob *Object) Render(target d2interface.Surface) { renderOffset := ob.Position.RenderOffset() target.PushTranslation( - int((renderOffset.X()-renderOffset.Y())*16), - int(((renderOffset.X() + renderOffset.Y()) * 8)), + int((renderOffset.X()-renderOffset.Y())*subtileWidth), + int(((renderOffset.X() + renderOffset.Y()) * subtileHeight)), ) if ob.highlight { diff --git a/d2core/d2map/d2mapentity/player.go b/d2core/d2map/d2mapentity/player.go index 2421369d..e3c25347 100644 --- a/d2core/d2map/d2mapentity/player.go +++ b/d2core/d2map/d2mapentity/player.go @@ -92,7 +92,7 @@ func (p *Player) Advance(tickTime float64) { } // skills are casted after the first half of the casting animation is played - isHalfDoneCasting := float64(p.composite.GetCurrentFrame()) / float64(p.composite.GetFrameCount()) >= 0.5 + isHalfDoneCasting := float64(p.composite.GetCurrentFrame())/float64(p.composite.GetFrameCount()) >= 0.5 if isHalfDoneCasting && p.onFinishedCasting != nil { p.onFinishedCasting() p.onFinishedCasting = nil @@ -111,15 +111,24 @@ func (p *Player) Advance(tickTime float64) { p.animationMode = p.composite.GetAnimationMode() } + charstats := p.composite.AssetManager.Records.Character.Stats[p.Class] + staminaDrain := float64(charstats.StaminaRunDrain) + + // This number has been determined by trying it out and checking if the stamina drain is + // the same as in d2 with the drain value from the assets. + // (We stopped the time for a lvl 1 babarian to loose all stamina which is around 25 seconds + // if i Remember correctly) + const magicStaminaDrainDivisor = 5 + // Drain and regenerate Stamina if p.IsRunning() && !p.atTarget() && !p.IsInTown() { - p.Stats.Stamina -= float64(p.composite.AssetManager.Records.Character.Stats[p.Class].StaminaRunDrain) * tickTime / 5 + p.Stats.Stamina -= staminaDrain * tickTime / magicStaminaDrainDivisor if p.Stats.Stamina <= 0 { p.SetSpeed(baseWalkSpeed) p.Stats.Stamina = 0 } } else if p.Stats.Stamina < float64(p.Stats.MaxStamina) { - p.Stats.Stamina += float64(p.composite.AssetManager.Records.Character.Stats[p.Class].StaminaRunDrain) * tickTime / 5 + p.Stats.Stamina += staminaDrain * tickTime / magicStaminaDrainDivisor if p.IsRunning() { p.SetSpeed(baseRunSpeed) } @@ -130,8 +139,8 @@ func (p *Player) Advance(tickTime float64) { func (p *Player) Render(target d2interface.Surface) { renderOffset := p.Position.RenderOffset() target.PushTranslation( - int((renderOffset.X()-renderOffset.Y())*16), - int(((renderOffset.X()+renderOffset.Y())*8)-5), + int((renderOffset.X()-renderOffset.Y())*subtileWidth), + int(((renderOffset.X()+renderOffset.Y())*subtileHeight)+subtileOffsetY), ) defer target.Pop() @@ -238,7 +247,7 @@ func (p *Player) GetVelocity() d2vector.Vector { // GetSize returns the current frame size func (p *Player) GetSize() (width, height int) { width, height = p.composite.GetSize() - // hack: we need to get full size of composite animations, currently only gets legs + // todo: we need to get full size of composite animations, currently only gets legs height = (height * 2) - (height / 2) return width, height diff --git a/d2core/d2map/d2mapgen/act1_overworld.go b/d2core/d2map/d2mapgen/act1_overworld.go index 7a2a68ac..b319abaf 100644 --- a/d2core/d2map/d2mapgen/act1_overworld.go +++ b/d2core/d2map/d2mapgen/act1_overworld.go @@ -12,17 +12,37 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapstamp" ) +const ( + presetA = iota + presetB + presetC + presetD + presetE + presetF +) + +const ( + wildernessDetailsRecordID = 2 +) + +const ( + mapWidth = 150 + mapHeight = mapWidth + mapMargin = 9 + autoFileIndex = d2mapstamp.AutoFileIndex +) + // GenerateAct1Overworld generates the map and entities for the first town and surrounding area. func (g *MapGenerator) GenerateAct1Overworld() { rand.Seed(g.engine.Seed()) - wilderness1Details := g.asset.Records.GetLevelDetails(2) + wilderness1Details := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID) - g.engine.ResetMap(d2enum.RegionAct1Town, 150, 150) + g.engine.ResetMap(d2enum.RegionAct1Town, mapWidth, mapHeight) mapWidth := g.engine.Size().Width mapHeight := g.engine.Size().Height - townStamp := g.engine.LoadStamp(d2enum.RegionAct1Town, 1, -1) + townStamp := g.engine.LoadStamp(d2enum.RegionAct1Town, presetB, autoFileIndex) townStamp.RegionPath() townSize := townStamp.Size() @@ -37,11 +57,19 @@ func (g *MapGenerator) GenerateAct1Overworld() { rightWaterBorderStamp := g.loadPreset(d2wilderness.WaterBorderEast, 0) rightWaterBorderStamp2 := g.loadPreset(d2wilderness.WaterBorderWest, 0) - for y := townSize.Height; y < mapHeight-9; y += 9 { - g.engine.PlaceStamp(rightWaterBorderStamp, mapWidth-17, y) - g.engine.PlaceStamp(rightWaterBorderStamp2, mapWidth-9, y) + mapInnerHeight := mapHeight - mapMargin + mapInnerWidth := mapWidth - mapMargin + + for y := townSize.Height; y < mapInnerHeight; y += mapMargin { + g.engine.PlaceStamp(rightWaterBorderStamp, mapInnerWidth-mapMargin, y) + g.engine.PlaceStamp(rightWaterBorderStamp2, mapInnerWidth, y) } - g.generateWilderness1TownSouth(mapWidth-wilderness1Details.SizeXNormal-14, townSize.Height) + + edgeOffset := 14 + startX := mapWidth - wilderness1Details.SizeXNormal - edgeOffset + startY := townSize.Height + + g.generateWilderness1TownSouth(startX, startY) case strings.Contains(townStamp.RegionPath(), "W1"): g.engine.PlaceStamp(townStamp, mapWidth-townSize.Width, mapHeight-townSize.Height) startX := mapWidth - townSize.Width - wilderness1Details.SizeXNormal @@ -53,36 +81,36 @@ func (g *MapGenerator) GenerateAct1Overworld() { } func (g *MapGenerator) generateWilderness1TownEast(startX, startY int) { - levelDetails := g.asset.Records.GetLevelDetails(2) + levelDetails := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID) fenceNorthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderNorth, 0), - g.loadPreset(d2wilderness.TreeBorderNorth, 1), - g.loadPreset(d2wilderness.TreeBorderNorth, 2), + g.loadPreset(d2wilderness.TreeBorderNorth, presetA), + g.loadPreset(d2wilderness.TreeBorderNorth, presetB), + g.loadPreset(d2wilderness.TreeBorderNorth, presetC), } fenceSouthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderSouth, 0), - g.loadPreset(d2wilderness.TreeBorderSouth, 1), - g.loadPreset(d2wilderness.TreeBorderSouth, 2), + g.loadPreset(d2wilderness.TreeBorderSouth, presetA), + g.loadPreset(d2wilderness.TreeBorderSouth, presetB), + g.loadPreset(d2wilderness.TreeBorderSouth, presetC), } fenceWestStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderWest, 0), - g.loadPreset(d2wilderness.TreeBorderWest, 1), - g.loadPreset(d2wilderness.TreeBorderWest, 2), + g.loadPreset(d2wilderness.TreeBorderWest, presetA), + g.loadPreset(d2wilderness.TreeBorderWest, presetB), + g.loadPreset(d2wilderness.TreeBorderWest, presetC), } fenceEastStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderEast, 0), - g.loadPreset(d2wilderness.TreeBorderEast, 1), - g.loadPreset(d2wilderness.TreeBorderEast, 2), + g.loadPreset(d2wilderness.TreeBorderEast, presetA), + g.loadPreset(d2wilderness.TreeBorderEast, presetB), + g.loadPreset(d2wilderness.TreeBorderEast, presetC), } - fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) - fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, 0) - fenceSouthEastStamp := g.loadPreset(d2wilderness.TreeBorderSouthEast, 0) - fenceWestEdge := g.loadPreset(d2wilderness.TreeBoxNorthEast, 0) + fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetA) + fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, presetA) + fenceSouthEastStamp := g.loadPreset(d2wilderness.TreeBorderSouthEast, presetA) + fenceWestEdge := g.loadPreset(d2wilderness.TreeBoxNorthEast, presetA) areaRect := d2geom.Rectangle{ Left: startX, @@ -118,29 +146,29 @@ func (g *MapGenerator) generateWilderness1TownEast(startX, startY int) { } func (g *MapGenerator) generateWilderness1TownSouth(startX, startY int) { - levelDetails := g.asset.Records.GetLevelDetails(2) + levelDetails := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID) fenceNorthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderNorth, 0), - g.loadPreset(d2wilderness.TreeBorderNorth, 1), - g.loadPreset(d2wilderness.TreeBorderNorth, 2), + g.loadPreset(d2wilderness.TreeBorderNorth, presetA), + g.loadPreset(d2wilderness.TreeBorderNorth, presetB), + g.loadPreset(d2wilderness.TreeBorderNorth, presetC), } fenceWestStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderWest, 0), - g.loadPreset(d2wilderness.TreeBorderWest, 1), - g.loadPreset(d2wilderness.TreeBorderWest, 2), + g.loadPreset(d2wilderness.TreeBorderWest, presetA), + g.loadPreset(d2wilderness.TreeBorderWest, presetB), + g.loadPreset(d2wilderness.TreeBorderWest, presetC), } fenceSouthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderSouth, 0), - g.loadPreset(d2wilderness.TreeBorderSouth, 1), - g.loadPreset(d2wilderness.TreeBorderSouth, 2), + g.loadPreset(d2wilderness.TreeBorderSouth, presetA), + g.loadPreset(d2wilderness.TreeBorderSouth, presetB), + g.loadPreset(d2wilderness.TreeBorderSouth, presetC), } - fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, 0) - fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) - fenceWaterBorderSouthEast := g.loadPreset(d2wilderness.WaterBorderEast, 1) + fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, presetA) + fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetB) + fenceWaterBorderSouthEast := g.loadPreset(d2wilderness.WaterBorderEast, presetC) areaRect := d2geom.Rectangle{ Left: startX + 2, @@ -171,35 +199,35 @@ func (g *MapGenerator) generateWilderness1TownSouth(startX, startY int) { } func (g *MapGenerator) generateWilderness1TownWest(startX, startY int) { - levelDetails := g.asset.Records.GetLevelDetails(2) + levelDetails := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID) - fenceEastEdge := g.loadPreset(d2wilderness.TreeBoxSouthWest, 0) - fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, 0) - fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, 0) - fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) + fenceEastEdge := g.loadPreset(d2wilderness.TreeBoxSouthWest, presetA) + fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, presetA) + fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, presetA) + fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetA) fenceSouthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderSouth, 0), - g.loadPreset(d2wilderness.TreeBorderSouth, 1), - g.loadPreset(d2wilderness.TreeBorderSouth, 2), + g.loadPreset(d2wilderness.TreeBorderSouth, presetA), + g.loadPreset(d2wilderness.TreeBorderSouth, presetB), + g.loadPreset(d2wilderness.TreeBorderSouth, presetC), } fenceNorthStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderNorth, 0), - g.loadPreset(d2wilderness.TreeBorderNorth, 1), - g.loadPreset(d2wilderness.TreeBorderNorth, 2), + g.loadPreset(d2wilderness.TreeBorderNorth, presetA), + g.loadPreset(d2wilderness.TreeBorderNorth, presetB), + g.loadPreset(d2wilderness.TreeBorderNorth, presetC), } fenceEastStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderEast, 0), - g.loadPreset(d2wilderness.TreeBorderEast, 1), - g.loadPreset(d2wilderness.TreeBorderEast, 2), + g.loadPreset(d2wilderness.TreeBorderEast, presetA), + g.loadPreset(d2wilderness.TreeBorderEast, presetB), + g.loadPreset(d2wilderness.TreeBorderEast, presetC), } fenceWestStamp := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.TreeBorderWest, 0), - g.loadPreset(d2wilderness.TreeBorderWest, 1), - g.loadPreset(d2wilderness.TreeBorderWest, 2), + g.loadPreset(d2wilderness.TreeBorderWest, presetA), + g.loadPreset(d2wilderness.TreeBorderWest, presetB), + g.loadPreset(d2wilderness.TreeBorderWest, presetC), } // Draw the north and south fences @@ -237,7 +265,7 @@ func (g *MapGenerator) generateWilderness1TownWest(startX, startY int) { } func (g *MapGenerator) generateWilderness1Contents(rect d2geom.Rectangle) { - levelDetails := g.asset.Records.GetLevelDetails(2) + levelDetails := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID) denOfEvil := g.loadPreset(d2wilderness.DenOfEvilEntrance, 0) denOfEvilLoc := d2geom.Point{ @@ -256,25 +284,25 @@ func (g *MapGenerator) generateWilderness1Contents(rect d2geom.Rectangle) { } stuff := []*d2mapstamp.Stamp{ - g.loadPreset(d2wilderness.StoneFill1, 0), - g.loadPreset(d2wilderness.StoneFill1, 1), - g.loadPreset(d2wilderness.StoneFill1, 2), - g.loadPreset(d2wilderness.StoneFill2, 0), - g.loadPreset(d2wilderness.StoneFill2, 1), - g.loadPreset(d2wilderness.StoneFill2, 2), - g.loadPreset(d2wilderness.Cottages1, 0), - g.loadPreset(d2wilderness.Cottages1, 1), - g.loadPreset(d2wilderness.Cottages1, 2), - g.loadPreset(d2wilderness.Cottages1, 3), - g.loadPreset(d2wilderness.Cottages1, 4), - g.loadPreset(d2wilderness.Cottages1, 5), - g.loadPreset(d2wilderness.FallenCamp1, 0), - g.loadPreset(d2wilderness.FallenCamp1, 1), - g.loadPreset(d2wilderness.FallenCamp1, 2), - g.loadPreset(d2wilderness.FallenCamp1, 3), - g.loadPreset(d2wilderness.Pond, 0), - g.loadPreset(d2wilderness.SwampFill1, 0), - g.loadPreset(d2wilderness.SwampFill2, 0), + g.loadPreset(d2wilderness.StoneFill1, presetA), + g.loadPreset(d2wilderness.StoneFill1, presetB), + g.loadPreset(d2wilderness.StoneFill1, presetC), + g.loadPreset(d2wilderness.StoneFill2, presetA), + g.loadPreset(d2wilderness.StoneFill2, presetB), + g.loadPreset(d2wilderness.StoneFill2, presetC), + g.loadPreset(d2wilderness.Cottages1, presetA), + g.loadPreset(d2wilderness.Cottages1, presetB), + g.loadPreset(d2wilderness.Cottages1, presetC), + g.loadPreset(d2wilderness.Cottages1, presetD), + g.loadPreset(d2wilderness.Cottages1, presetE), + g.loadPreset(d2wilderness.Cottages1, presetF), + g.loadPreset(d2wilderness.FallenCamp1, presetA), + g.loadPreset(d2wilderness.FallenCamp1, presetB), + g.loadPreset(d2wilderness.FallenCamp1, presetC), + g.loadPreset(d2wilderness.FallenCamp1, presetD), + g.loadPreset(d2wilderness.Pond, presetA), + g.loadPreset(d2wilderness.SwampFill1, presetA), + g.loadPreset(d2wilderness.SwampFill2, presetA), } g.engine.PlaceStamp(denOfEvil, denOfEvilLoc.X, denOfEvilLoc.Y) diff --git a/d2core/d2map/d2maprenderer/renderer.go b/d2core/d2map/d2maprenderer/renderer.go index 0b59f8d0..e673e358 100644 --- a/d2core/d2map/d2maprenderer/renderer.go +++ b/d2core/d2map/d2maprenderer/renderer.go @@ -534,7 +534,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) // what are these magic numbers?? + target.PushTranslation(-20, 10+(i+1)*14) // nolint:gomnd // just for debug target.DrawTextf("s: %v-%v", wall.Style, wall.Sequence) target.Pop() } diff --git a/d2core/d2map/d2maprenderer/tile_cache.go b/d2core/d2map/d2maprenderer/tile_cache.go index 110c7a13..cdff19fb 100644 --- a/d2core/d2map/d2maprenderer/tile_cache.go +++ b/d2core/d2map/d2maprenderer/tile_cache.go @@ -10,6 +10,13 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2common/d2util" ) +const ( + tileMinHeight int16 = 32 + shadowAdjustY int32 = 80 + defaultFloorTileWidth = 10 + defaultFloorTileHeight = 10 +) + func (mr *MapRenderer) generateTileCache() { var err error mr.palette, err = mr.loadPaletteForAct(d2enum.RegionIdType(mr.mapEngine.LevelType().ID)) @@ -51,8 +58,8 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) { log.Printf("Could not locate tile Style:%d, Seq: %d, Type: %d\n", tile.Style, tile.Sequence, 0) tileData = append(tileData, &d2dt1.Tile{}) - tileData[0].Width = 10 - tileData[0].Height = 10 + tileData[0].Width = defaultFloorTileWidth + tileData[0].Height = defaultFloorTileHeight } else { if !tileOptions[0].MaterialFlags.Lava { tileData = append(tileData, &tileOptions[tile.RandomIndex]) @@ -106,8 +113,10 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord) { } } +const shadowTileType = 13 + func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) { - tileOptions := mr.mapEngine.GetTiles(int(tile.Style), int(tile.Sequence), 13) + tileOptions := mr.mapEngine.GetTiles(int(tile.Style), int(tile.Sequence), shadowTileType) var tileData *d2dt1.Tile @@ -126,14 +135,14 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) { for _, block := range tileData.Blocks { tileMinY = d2math.MinInt32(tileMinY, int32(block.Y)) - tileMaxY = d2math.MaxInt32(tileMaxY, int32(block.Y+32)) + tileMaxY = d2math.MaxInt32(tileMaxY, int32(block.Y+tileMinHeight)) } tileYOffset := -tileMinY tileHeight := int(tileMaxY - tileMinY) - tile.YAdjust = int(tileMinY + 80) + tile.YAdjust = int(tileMinY + shadowAdjustY) - cachedImage := mr.getImageCacheRecord(tile.Style, tile.Sequence, 13, tile.RandomIndex) + cachedImage := mr.getImageCacheRecord(tile.Style, tile.Sequence, d2enum.TileShadow, tile.RandomIndex) if cachedImage != nil { return } @@ -152,7 +161,7 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) { log.Print(err) } - mr.setImageCacheRecord(tile.Style, tile.Sequence, 13, tile.RandomIndex, image) + mr.setImageCacheRecord(tile.Style, tile.Sequence, d2enum.TileShadow, tile.RandomIndex, image) } func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord) { diff --git a/d2core/d2map/d2mapstamp/factory.go b/d2core/d2map/d2mapstamp/factory.go index bc9e4355..479c6ef5 100644 --- a/d2core/d2map/d2mapstamp/factory.go +++ b/d2core/d2map/d2mapstamp/factory.go @@ -13,6 +13,10 @@ import ( "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" ) +const ( + AutoFileIndex = -1 +) + // NewStampFactory creates a MapStamp factory instance func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory { return &StampFactory{asset, entity} diff --git a/d2core/d2ui/button.go b/d2core/d2ui/button.go index 548888d1..e695e5b7 100644 --- a/d2core/d2ui/button.go +++ b/d2core/d2ui/button.go @@ -43,8 +43,8 @@ const ( ButtonTypeSquareClose ButtonType = 20 ButtonTypeSkillTreeTab ButtonType = 21 - ButtonNoFixedWidth int = -1 - ButtonNoFixedHeight int = -1 + ButtonNoFixedWidth int = -1 + ButtonNoFixedHeight int = -1 ) const ( @@ -102,6 +102,13 @@ const ( buttonBuySellSegmentsY = 1 buttonBuySellDisabledFrame = 1 + buttonSkillTreeTabXSegments = 1 + buttonSkillTreeTabYSegments = 1 + buttonSkillTreeTabDisabledFrame = 7 + buttonSkillTreeTabBaseFrame = 7 + buttonSkillTreeTabFixedWidth = 93 + buttonSkillTreeTabFixedHeight = 107 + buttonRunSegmentsX = 1 buttonRunSegmentsY = 1 buttonRunDisabledFrame = -1 @@ -207,18 +214,18 @@ func getButtonLayouts() map[ButtonType]ButtonLayout { LabelColor: greyAlpha100, }, ButtonTypeSkillTreeTab: { - XSegments: 1, - YSegments: 1, - DisabledFrame: 7, + XSegments: buttonSkillTreeTabXSegments, + YSegments: buttonSkillTreeTabYSegments, + DisabledFrame: buttonSkillTreeTabDisabledFrame, + BaseFrame: buttonSkillTreeTabBaseFrame, ResourceName: d2resource.SkillsPanelAmazon, PaletteName: d2resource.PaletteSky, Toggleable: false, FontPath: d2resource.Font16, AllowFrameChange: false, - BaseFrame: 7, HasImage: false, - FixedWidth: 93, - FixedHeight: 107, + FixedWidth: buttonSkillTreeTabFixedWidth, + FixedHeight: buttonSkillTreeTabFixedHeight, LabelColor: whiteAlpha100, }, } @@ -272,15 +279,15 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button { if buttonLayout.FixedWidth > 0 { btn.width = buttonLayout.FixedWidth } else { - for i := 0; i < buttonLayout.XSegments; i++ { - w, _, err := buttonSprite.GetFrameSize(i) - if err != nil { - log.Print(err) - return nil - } + for i := 0; i < buttonLayout.XSegments; i++ { + w, _, err := buttonSprite.GetFrameSize(i) + if err != nil { + log.Print(err) + return nil + } - btn.width += w - } + btn.width += w + } } if buttonLayout.FixedHeight > 0 { diff --git a/d2game/d2player/escape_menu.go b/d2game/d2player/escape_menu.go index 79215a89..e2872695 100644 --- a/d2game/d2player/escape_menu.go +++ b/d2game/d2player/escape_menu.go @@ -59,6 +59,10 @@ const ( optAutomapShowNames ) +const ( + singleFrame = time.Millisecond * 16 +) + // EscapeMenu represents the in-game menu that shows up when the esc key is pressed type EscapeMenu struct { isOpen bool @@ -449,7 +453,7 @@ func (m *EscapeMenu) setLayout(id layoutID) { m.rightPent.SetVisible(false) go func() { - time.Sleep(16 * time.Millisecond) + time.Sleep(singleFrame) m.onHoverElement(m.layouts[id].currentEl) m.leftPent.SetVisible(true) m.rightPent.SetVisible(true) diff --git a/d2game/d2player/help/help.go b/d2game/d2player/help/help.go index 34a26695..ffcbfb04 100644 --- a/d2game/d2player/help/help.go +++ b/d2game/d2player/help/help.go @@ -16,13 +16,13 @@ import ( ) const ( - tlCornerFrame = iota - lFrame - tFrameLHalf - tFrameRHalf - trCornerFrameTHalf - trCornerFrameRHalf - rFrame + frameTopLeft = iota + frameBottomLeft + frameTopMiddleLeft + frameTopMiddleRight + frameTopRightNoCorner + frameTopRight + frameBottomRight ) const ( @@ -34,9 +34,10 @@ const ( windowWidth = 800 bulletOffsetY = 14 + lineOffset = 5 // the title of the panel - titleLabelOffsetX = -30 + titleLabelOffsetX = -37 // for the bulleted list near the top of the screen listRootX = 100 @@ -48,8 +49,10 @@ const ( listBulletX = listRootX - listBulletOffsetX // the close button for the help panel - closeButtonX = 685 - closeButtonY = 25 + closeButtonX = 685 + closeButtonY = 25 + closeButtonLabelX = 680 + closeButtonLabelY = 60 // the rest of these are for text with a line and dot, towards the bottom of the screen newStatsLabelX = 222 @@ -217,14 +220,42 @@ func (h *Overlay) IsInRect(px, py int) bool { // Load the overlay graphical assets func (h *Overlay) Load() { - var ( - x = 0 - y = 0 - prevX = 0 - prevY = 0 + /* + the 800x600 help screen dc6 file frames look like this + the position we set for frames is the lower-left corner x,y + +----+------------------+-------------------+------------+----+ + | 1 | 3 | 4 | 5 | 6 | + | |------------------+-------------------| | | + | | | | | + | | | | | + +----+ +------------+----+ + | 2 | | 7 | + | | | | + | | | | + +----+ +----+ + */ + const ( + // if you add up frame widths 1,3,4,5,6 you get (65+255+255+245+20) = 840 + magicHelpBorderOffsetX = -40 ) - for frameIndex := 0; frameIndex < 7; frameIndex++ { + frames := []int{ + frameTopLeft, + frameBottomLeft, + frameTopMiddleLeft, + frameTopMiddleRight, + frameTopRightNoCorner, + frameTopRight, + frameBottomRight, + } + + left, top := 0, 0 + firstFrameWidth := 0 + prevY := 0 + prevWidth := 0 + currentX, currentY := left, top + + for _, frameIndex := range frames { f, err := h.uiManager.NewSprite(d2resource.HelpBorder, d2resource.PaletteSky) if err != nil { log.Print(err) @@ -235,38 +266,36 @@ func (h *Overlay) Load() { log.Print(err) } - ww, hh := f.GetCurrentFrameSize() - //fmt.Printf("Help frame %d size: %d, %d\n", frameIndex, ww, hh) + frameWidth, frameHeight := f.GetCurrentFrameSize() switch frameIndex { - case tlCornerFrame: - y = hh - case lFrame: - y = hh + prevY - case tFrameLHalf: - y = hh - x = 65 - case tFrameRHalf: - y = hh - x = windowWidth - ww - 245 - case trCornerFrameTHalf: - y = hh - x = windowWidth - ww - 20 - case trCornerFrameRHalf: - y = hh - x = windowWidth - ww - case rFrame: - y = hh + prevY - x = windowWidth - ww + case frameTopLeft: + currentY += frameHeight + firstFrameWidth = frameWidth + case frameBottomLeft: + currentY += frameHeight + case frameTopMiddleLeft: + currentX = firstFrameWidth + currentY = top + frameHeight + case frameTopMiddleRight: + currentY = top + frameHeight + currentX += prevWidth + currentX += magicHelpBorderOffsetX + case frameTopRightNoCorner: + currentY = top + frameHeight + currentX += prevWidth + case frameTopRight: + currentY = top + frameHeight + currentX += prevWidth + case frameBottomRight: + currentY = prevY + frameHeight } - //y += 50 + prevY = currentY + prevWidth = frameWidth - _ = prevX + f.SetPosition(currentX, currentY) - prevX = x - prevY = y - f.SetPosition(x, y) h.frames = append(h.frames, f) } @@ -290,7 +319,7 @@ func (h *Overlay) Load() { newLabel = h.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky) newLabel.SetText(d2tbl.TranslateString("strClose")) // "Close" - newLabel.SetPosition(680, 60) + newLabel.SetPosition(closeButtonLabelX, closeButtonLabelY) h.text = append(h.text, newLabel) // Bullets @@ -301,6 +330,7 @@ func (h *Overlay) Load() { // TODO "Alt" should be hotkey // "Hold down <%s> to highlight items on the ground" {text: fmt.Sprintf(d2tbl.TranslateString("StrHelp3"), "Alt")}, + // TODO "Shift" should be hotkey // "Hold down <%s> to attack while standing still" {text: fmt.Sprintf(d2tbl.TranslateString("StrHelp4"), "Shift")}, @@ -536,9 +566,9 @@ func (h *Overlay) createCallout(c callout) { l := line{ StartX: c.LabelX, - StartY: c.LabelY + hh + 5, + StartY: c.LabelY + hh + lineOffset, MoveX: 0, - MoveY: c.DotY - c.LabelY - hh - 5, + MoveY: c.DotY - c.LabelY - hh - lineOffset, Color: color.White, }