1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-18 02:16:23 -05:00

removed a bunch of magic number lint errors (#785)

* removed magic numbers from d2ui/button.go

* removed a bunch of magic number lint errors
This commit is contained in:
gravestench 2020-10-23 14:00:51 +01:00 committed by GitHub
parent 2704a23289
commit 16a82442bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 264 additions and 159 deletions

View File

@ -44,7 +44,10 @@ const (
rareJewelAffixMax = 4 rareJewelAffixMax = 4
) )
const maxAffixesOnMagicItem = 2 const (
maxAffixesOnMagicItem = 2
sidesOnACoin = 2 // for random coin flip
)
// static check to ensure Item implements Item // static check to ensure Item implements Item
var _ d2item.Item = &Item{} var _ d2item.Item = &Item{}
@ -362,7 +365,8 @@ func (i *Item) pickRandomAffixes(max, totalMax int,
for numPicks := 0; numPicks < max; numPicks++ { for numPicks := 0; numPicks < max; numPicks++ {
matches := i.factory.FindMatchingAffixes(i.CommonRecord(), affixMap) 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()) affixCount := len(i.PrefixRecords()) + len(i.SuffixRecords())
if len(i.PrefixRecords()) > max || affixCount > totalMax { if len(i.PrefixRecords()) > max || affixCount > totalMax {
break break

View File

@ -86,9 +86,15 @@ func getRandomTile(tiles []d2dt1.Tile, x, y int, seed int64) byte {
tileSeed = uint64(seed) + uint64(x) tileSeed = uint64(seed) + uint64(x)
tileSeed *= uint64(y) tileSeed *= uint64(y)
tileSeed ^= tileSeed << 13 const (
tileSeed ^= tileSeed >> 17 xorshiftA = 13
tileSeed ^= tileSeed << 5 xorshiftB = 17
xorshiftC = 5
)
tileSeed ^= tileSeed << xorshiftA
tileSeed ^= tileSeed >> xorshiftB
tileSeed ^= tileSeed << xorshiftC
weightSum := 0 weightSum := 0

View File

@ -27,7 +27,7 @@ func (m *MapEngine) checkLos(start, end d2vector.Position) (bool, d2vector.Posit
if N == 0 { if N == 0 {
divN = 0.0 divN = 0.0
} else { } else {
divN = 1.0 / N divN = 1.0 / N // nolint:gomnd // we're just taking inverse...
} }
xstep := dx * divN xstep := dx * divN

View File

@ -17,6 +17,10 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
) )
const (
subtilesPerTile = 5
)
// NewMapEntityFactory creates a MapEntityFactory instance with the given asset manager // NewMapEntityFactory creates a MapEntityFactory instance with the given asset manager
func NewMapEntityFactory(asset *d2asset.AssetManager) (*MapEntityFactory, error) { func NewMapEntityFactory(asset *d2asset.AssetManager) (*MapEntityFactory, error) {
itemFactory, err := diablo2item.NewItemFactory(asset) itemFactory, err := diablo2item.NewItemFactory(asset)
@ -166,7 +170,7 @@ func (f *MapEntityFactory) NewItem(x, y int, codes ...string) (*Item, error) {
animation.PlayForward() animation.PlayForward()
animation.SetPlayLoop(false) animation.SetPlayLoop(false)
entity := NewAnimatedEntity(x*5, y*5, animation) entity := NewAnimatedEntity(x*subtilesPerTile, y*subtilesPerTile, animation)
result := &Item{ result := &Item{
AnimatedEntity: entity, AnimatedEntity: entity,

View File

@ -79,8 +79,8 @@ func (ob *Object) Selectable() bool {
func (ob *Object) Render(target d2interface.Surface) { func (ob *Object) Render(target d2interface.Surface) {
renderOffset := ob.Position.RenderOffset() renderOffset := ob.Position.RenderOffset()
target.PushTranslation( target.PushTranslation(
int((renderOffset.X()-renderOffset.Y())*16), int((renderOffset.X()-renderOffset.Y())*subtileWidth),
int(((renderOffset.X() + renderOffset.Y()) * 8)), int(((renderOffset.X() + renderOffset.Y()) * subtileHeight)),
) )
if ob.highlight { if ob.highlight {

View File

@ -92,7 +92,7 @@ func (p *Player) Advance(tickTime float64) {
} }
// skills are casted after the first half of the casting animation is played // 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 { if isHalfDoneCasting && p.onFinishedCasting != nil {
p.onFinishedCasting() p.onFinishedCasting()
p.onFinishedCasting = nil p.onFinishedCasting = nil
@ -111,15 +111,24 @@ func (p *Player) Advance(tickTime float64) {
p.animationMode = p.composite.GetAnimationMode() 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 // Drain and regenerate Stamina
if p.IsRunning() && !p.atTarget() && !p.IsInTown() { 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 { if p.Stats.Stamina <= 0 {
p.SetSpeed(baseWalkSpeed) p.SetSpeed(baseWalkSpeed)
p.Stats.Stamina = 0 p.Stats.Stamina = 0
} }
} else if p.Stats.Stamina < float64(p.Stats.MaxStamina) { } 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() { if p.IsRunning() {
p.SetSpeed(baseRunSpeed) p.SetSpeed(baseRunSpeed)
} }
@ -130,8 +139,8 @@ func (p *Player) Advance(tickTime float64) {
func (p *Player) Render(target d2interface.Surface) { func (p *Player) Render(target d2interface.Surface) {
renderOffset := p.Position.RenderOffset() renderOffset := p.Position.RenderOffset()
target.PushTranslation( target.PushTranslation(
int((renderOffset.X()-renderOffset.Y())*16), int((renderOffset.X()-renderOffset.Y())*subtileWidth),
int(((renderOffset.X()+renderOffset.Y())*8)-5), int(((renderOffset.X()+renderOffset.Y())*subtileHeight)+subtileOffsetY),
) )
defer target.Pop() defer target.Pop()
@ -238,7 +247,7 @@ func (p *Player) GetVelocity() d2vector.Vector {
// GetSize returns the current frame size // GetSize returns the current frame size
func (p *Player) GetSize() (width, height int) { func (p *Player) GetSize() (width, height int) {
width, height = p.composite.GetSize() 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) height = (height * 2) - (height / 2)
return width, height return width, height

View File

@ -12,17 +12,37 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapstamp" "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. // GenerateAct1Overworld generates the map and entities for the first town and surrounding area.
func (g *MapGenerator) GenerateAct1Overworld() { func (g *MapGenerator) GenerateAct1Overworld() {
rand.Seed(g.engine.Seed()) 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 mapWidth := g.engine.Size().Width
mapHeight := g.engine.Size().Height mapHeight := g.engine.Size().Height
townStamp := g.engine.LoadStamp(d2enum.RegionAct1Town, 1, -1) townStamp := g.engine.LoadStamp(d2enum.RegionAct1Town, presetB, autoFileIndex)
townStamp.RegionPath() townStamp.RegionPath()
townSize := townStamp.Size() townSize := townStamp.Size()
@ -37,11 +57,19 @@ func (g *MapGenerator) GenerateAct1Overworld() {
rightWaterBorderStamp := g.loadPreset(d2wilderness.WaterBorderEast, 0) rightWaterBorderStamp := g.loadPreset(d2wilderness.WaterBorderEast, 0)
rightWaterBorderStamp2 := g.loadPreset(d2wilderness.WaterBorderWest, 0) rightWaterBorderStamp2 := g.loadPreset(d2wilderness.WaterBorderWest, 0)
for y := townSize.Height; y < mapHeight-9; y += 9 { mapInnerHeight := mapHeight - mapMargin
g.engine.PlaceStamp(rightWaterBorderStamp, mapWidth-17, y) mapInnerWidth := mapWidth - mapMargin
g.engine.PlaceStamp(rightWaterBorderStamp2, mapWidth-9, y)
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"): case strings.Contains(townStamp.RegionPath(), "W1"):
g.engine.PlaceStamp(townStamp, mapWidth-townSize.Width, mapHeight-townSize.Height) g.engine.PlaceStamp(townStamp, mapWidth-townSize.Width, mapHeight-townSize.Height)
startX := mapWidth - townSize.Width - wilderness1Details.SizeXNormal startX := mapWidth - townSize.Width - wilderness1Details.SizeXNormal
@ -53,36 +81,36 @@ func (g *MapGenerator) GenerateAct1Overworld() {
} }
func (g *MapGenerator) generateWilderness1TownEast(startX, startY int) { func (g *MapGenerator) generateWilderness1TownEast(startX, startY int) {
levelDetails := g.asset.Records.GetLevelDetails(2) levelDetails := g.asset.Records.GetLevelDetails(wildernessDetailsRecordID)
fenceNorthStamp := []*d2mapstamp.Stamp{ fenceNorthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderNorth, 0), g.loadPreset(d2wilderness.TreeBorderNorth, presetA),
g.loadPreset(d2wilderness.TreeBorderNorth, 1), g.loadPreset(d2wilderness.TreeBorderNorth, presetB),
g.loadPreset(d2wilderness.TreeBorderNorth, 2), g.loadPreset(d2wilderness.TreeBorderNorth, presetC),
} }
fenceSouthStamp := []*d2mapstamp.Stamp{ fenceSouthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderSouth, 0), g.loadPreset(d2wilderness.TreeBorderSouth, presetA),
g.loadPreset(d2wilderness.TreeBorderSouth, 1), g.loadPreset(d2wilderness.TreeBorderSouth, presetB),
g.loadPreset(d2wilderness.TreeBorderSouth, 2), g.loadPreset(d2wilderness.TreeBorderSouth, presetC),
} }
fenceWestStamp := []*d2mapstamp.Stamp{ fenceWestStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderWest, 0), g.loadPreset(d2wilderness.TreeBorderWest, presetA),
g.loadPreset(d2wilderness.TreeBorderWest, 1), g.loadPreset(d2wilderness.TreeBorderWest, presetB),
g.loadPreset(d2wilderness.TreeBorderWest, 2), g.loadPreset(d2wilderness.TreeBorderWest, presetC),
} }
fenceEastStamp := []*d2mapstamp.Stamp{ fenceEastStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderEast, 0), g.loadPreset(d2wilderness.TreeBorderEast, presetA),
g.loadPreset(d2wilderness.TreeBorderEast, 1), g.loadPreset(d2wilderness.TreeBorderEast, presetB),
g.loadPreset(d2wilderness.TreeBorderEast, 2), g.loadPreset(d2wilderness.TreeBorderEast, presetC),
} }
fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetA)
fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, 0) fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, presetA)
fenceSouthEastStamp := g.loadPreset(d2wilderness.TreeBorderSouthEast, 0) fenceSouthEastStamp := g.loadPreset(d2wilderness.TreeBorderSouthEast, presetA)
fenceWestEdge := g.loadPreset(d2wilderness.TreeBoxNorthEast, 0) fenceWestEdge := g.loadPreset(d2wilderness.TreeBoxNorthEast, presetA)
areaRect := d2geom.Rectangle{ areaRect := d2geom.Rectangle{
Left: startX, Left: startX,
@ -118,29 +146,29 @@ func (g *MapGenerator) generateWilderness1TownEast(startX, startY int) {
} }
func (g *MapGenerator) generateWilderness1TownSouth(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{ fenceNorthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderNorth, 0), g.loadPreset(d2wilderness.TreeBorderNorth, presetA),
g.loadPreset(d2wilderness.TreeBorderNorth, 1), g.loadPreset(d2wilderness.TreeBorderNorth, presetB),
g.loadPreset(d2wilderness.TreeBorderNorth, 2), g.loadPreset(d2wilderness.TreeBorderNorth, presetC),
} }
fenceWestStamp := []*d2mapstamp.Stamp{ fenceWestStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderWest, 0), g.loadPreset(d2wilderness.TreeBorderWest, presetA),
g.loadPreset(d2wilderness.TreeBorderWest, 1), g.loadPreset(d2wilderness.TreeBorderWest, presetB),
g.loadPreset(d2wilderness.TreeBorderWest, 2), g.loadPreset(d2wilderness.TreeBorderWest, presetC),
} }
fenceSouthStamp := []*d2mapstamp.Stamp{ fenceSouthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderSouth, 0), g.loadPreset(d2wilderness.TreeBorderSouth, presetA),
g.loadPreset(d2wilderness.TreeBorderSouth, 1), g.loadPreset(d2wilderness.TreeBorderSouth, presetB),
g.loadPreset(d2wilderness.TreeBorderSouth, 2), g.loadPreset(d2wilderness.TreeBorderSouth, presetC),
} }
fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, 0) fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, presetA)
fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetB)
fenceWaterBorderSouthEast := g.loadPreset(d2wilderness.WaterBorderEast, 1) fenceWaterBorderSouthEast := g.loadPreset(d2wilderness.WaterBorderEast, presetC)
areaRect := d2geom.Rectangle{ areaRect := d2geom.Rectangle{
Left: startX + 2, Left: startX + 2,
@ -171,35 +199,35 @@ func (g *MapGenerator) generateWilderness1TownSouth(startX, startY int) {
} }
func (g *MapGenerator) generateWilderness1TownWest(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) fenceEastEdge := g.loadPreset(d2wilderness.TreeBoxSouthWest, presetA)
fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, 0) fenceNorthWestStamp := g.loadPreset(d2wilderness.TreeBorderNorthWest, presetA)
fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, 0) fenceNorthEastStamp := g.loadPreset(d2wilderness.TreeBorderNorthEast, presetA)
fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, 0) fenceSouthWestStamp := g.loadPreset(d2wilderness.TreeBorderSouthWest, presetA)
fenceSouthStamp := []*d2mapstamp.Stamp{ fenceSouthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderSouth, 0), g.loadPreset(d2wilderness.TreeBorderSouth, presetA),
g.loadPreset(d2wilderness.TreeBorderSouth, 1), g.loadPreset(d2wilderness.TreeBorderSouth, presetB),
g.loadPreset(d2wilderness.TreeBorderSouth, 2), g.loadPreset(d2wilderness.TreeBorderSouth, presetC),
} }
fenceNorthStamp := []*d2mapstamp.Stamp{ fenceNorthStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderNorth, 0), g.loadPreset(d2wilderness.TreeBorderNorth, presetA),
g.loadPreset(d2wilderness.TreeBorderNorth, 1), g.loadPreset(d2wilderness.TreeBorderNorth, presetB),
g.loadPreset(d2wilderness.TreeBorderNorth, 2), g.loadPreset(d2wilderness.TreeBorderNorth, presetC),
} }
fenceEastStamp := []*d2mapstamp.Stamp{ fenceEastStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderEast, 0), g.loadPreset(d2wilderness.TreeBorderEast, presetA),
g.loadPreset(d2wilderness.TreeBorderEast, 1), g.loadPreset(d2wilderness.TreeBorderEast, presetB),
g.loadPreset(d2wilderness.TreeBorderEast, 2), g.loadPreset(d2wilderness.TreeBorderEast, presetC),
} }
fenceWestStamp := []*d2mapstamp.Stamp{ fenceWestStamp := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.TreeBorderWest, 0), g.loadPreset(d2wilderness.TreeBorderWest, presetA),
g.loadPreset(d2wilderness.TreeBorderWest, 1), g.loadPreset(d2wilderness.TreeBorderWest, presetB),
g.loadPreset(d2wilderness.TreeBorderWest, 2), g.loadPreset(d2wilderness.TreeBorderWest, presetC),
} }
// Draw the north and south fences // Draw the north and south fences
@ -237,7 +265,7 @@ func (g *MapGenerator) generateWilderness1TownWest(startX, startY int) {
} }
func (g *MapGenerator) generateWilderness1Contents(rect d2geom.Rectangle) { 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) denOfEvil := g.loadPreset(d2wilderness.DenOfEvilEntrance, 0)
denOfEvilLoc := d2geom.Point{ denOfEvilLoc := d2geom.Point{
@ -256,25 +284,25 @@ func (g *MapGenerator) generateWilderness1Contents(rect d2geom.Rectangle) {
} }
stuff := []*d2mapstamp.Stamp{ stuff := []*d2mapstamp.Stamp{
g.loadPreset(d2wilderness.StoneFill1, 0), g.loadPreset(d2wilderness.StoneFill1, presetA),
g.loadPreset(d2wilderness.StoneFill1, 1), g.loadPreset(d2wilderness.StoneFill1, presetB),
g.loadPreset(d2wilderness.StoneFill1, 2), g.loadPreset(d2wilderness.StoneFill1, presetC),
g.loadPreset(d2wilderness.StoneFill2, 0), g.loadPreset(d2wilderness.StoneFill2, presetA),
g.loadPreset(d2wilderness.StoneFill2, 1), g.loadPreset(d2wilderness.StoneFill2, presetB),
g.loadPreset(d2wilderness.StoneFill2, 2), g.loadPreset(d2wilderness.StoneFill2, presetC),
g.loadPreset(d2wilderness.Cottages1, 0), g.loadPreset(d2wilderness.Cottages1, presetA),
g.loadPreset(d2wilderness.Cottages1, 1), g.loadPreset(d2wilderness.Cottages1, presetB),
g.loadPreset(d2wilderness.Cottages1, 2), g.loadPreset(d2wilderness.Cottages1, presetC),
g.loadPreset(d2wilderness.Cottages1, 3), g.loadPreset(d2wilderness.Cottages1, presetD),
g.loadPreset(d2wilderness.Cottages1, 4), g.loadPreset(d2wilderness.Cottages1, presetE),
g.loadPreset(d2wilderness.Cottages1, 5), g.loadPreset(d2wilderness.Cottages1, presetF),
g.loadPreset(d2wilderness.FallenCamp1, 0), g.loadPreset(d2wilderness.FallenCamp1, presetA),
g.loadPreset(d2wilderness.FallenCamp1, 1), g.loadPreset(d2wilderness.FallenCamp1, presetB),
g.loadPreset(d2wilderness.FallenCamp1, 2), g.loadPreset(d2wilderness.FallenCamp1, presetC),
g.loadPreset(d2wilderness.FallenCamp1, 3), g.loadPreset(d2wilderness.FallenCamp1, presetD),
g.loadPreset(d2wilderness.Pond, 0), g.loadPreset(d2wilderness.Pond, presetA),
g.loadPreset(d2wilderness.SwampFill1, 0), g.loadPreset(d2wilderness.SwampFill1, presetA),
g.loadPreset(d2wilderness.SwampFill2, 0), g.loadPreset(d2wilderness.SwampFill2, presetA),
} }
g.engine.PlaceStamp(denOfEvil, denOfEvilLoc.X, denOfEvilLoc.Y) g.engine.PlaceStamp(denOfEvil, denOfEvilLoc.X, denOfEvilLoc.Y)

View File

@ -534,7 +534,7 @@ func (mr *MapRenderer) renderTileDebug(ax, ay, debugVisLevel int, target d2inter
for i, wall := range tile.Components.Walls { for i, wall := range tile.Components.Walls {
if wall.Type.Special() { 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.DrawTextf("s: %v-%v", wall.Style, wall.Sequence)
target.Pop() target.Pop()
} }

View File

@ -10,6 +10,13 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
) )
const (
tileMinHeight int16 = 32
shadowAdjustY int32 = 80
defaultFloorTileWidth = 10
defaultFloorTileHeight = 10
)
func (mr *MapRenderer) generateTileCache() { func (mr *MapRenderer) generateTileCache() {
var err error var err error
mr.palette, err = mr.loadPaletteForAct(d2enum.RegionIdType(mr.mapEngine.LevelType().ID)) 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) log.Printf("Could not locate tile Style:%d, Seq: %d, Type: %d\n", tile.Style, tile.Sequence, 0)
tileData = append(tileData, &d2dt1.Tile{}) tileData = append(tileData, &d2dt1.Tile{})
tileData[0].Width = 10 tileData[0].Width = defaultFloorTileWidth
tileData[0].Height = 10 tileData[0].Height = defaultFloorTileHeight
} else { } else {
if !tileOptions[0].MaterialFlags.Lava { if !tileOptions[0].MaterialFlags.Lava {
tileData = append(tileData, &tileOptions[tile.RandomIndex]) 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) { 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 var tileData *d2dt1.Tile
@ -126,14 +135,14 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) {
for _, block := range tileData.Blocks { for _, block := range tileData.Blocks {
tileMinY = d2math.MinInt32(tileMinY, int32(block.Y)) 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 tileYOffset := -tileMinY
tileHeight := int(tileMaxY - 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 { if cachedImage != nil {
return return
} }
@ -152,7 +161,7 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord) {
log.Print(err) 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) { func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord) {

View File

@ -13,6 +13,10 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
) )
const (
AutoFileIndex = -1
)
// NewStampFactory creates a MapStamp factory instance // NewStampFactory creates a MapStamp factory instance
func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory { func NewStampFactory(asset *d2asset.AssetManager, entity *d2mapentity.MapEntityFactory) *StampFactory {
return &StampFactory{asset, entity} return &StampFactory{asset, entity}

View File

@ -43,8 +43,8 @@ const (
ButtonTypeSquareClose ButtonType = 20 ButtonTypeSquareClose ButtonType = 20
ButtonTypeSkillTreeTab ButtonType = 21 ButtonTypeSkillTreeTab ButtonType = 21
ButtonNoFixedWidth int = -1 ButtonNoFixedWidth int = -1
ButtonNoFixedHeight int = -1 ButtonNoFixedHeight int = -1
) )
const ( const (
@ -102,6 +102,13 @@ const (
buttonBuySellSegmentsY = 1 buttonBuySellSegmentsY = 1
buttonBuySellDisabledFrame = 1 buttonBuySellDisabledFrame = 1
buttonSkillTreeTabXSegments = 1
buttonSkillTreeTabYSegments = 1
buttonSkillTreeTabDisabledFrame = 7
buttonSkillTreeTabBaseFrame = 7
buttonSkillTreeTabFixedWidth = 93
buttonSkillTreeTabFixedHeight = 107
buttonRunSegmentsX = 1 buttonRunSegmentsX = 1
buttonRunSegmentsY = 1 buttonRunSegmentsY = 1
buttonRunDisabledFrame = -1 buttonRunDisabledFrame = -1
@ -207,18 +214,18 @@ func getButtonLayouts() map[ButtonType]ButtonLayout {
LabelColor: greyAlpha100, LabelColor: greyAlpha100,
}, },
ButtonTypeSkillTreeTab: { ButtonTypeSkillTreeTab: {
XSegments: 1, XSegments: buttonSkillTreeTabXSegments,
YSegments: 1, YSegments: buttonSkillTreeTabYSegments,
DisabledFrame: 7, DisabledFrame: buttonSkillTreeTabDisabledFrame,
BaseFrame: buttonSkillTreeTabBaseFrame,
ResourceName: d2resource.SkillsPanelAmazon, ResourceName: d2resource.SkillsPanelAmazon,
PaletteName: d2resource.PaletteSky, PaletteName: d2resource.PaletteSky,
Toggleable: false, Toggleable: false,
FontPath: d2resource.Font16, FontPath: d2resource.Font16,
AllowFrameChange: false, AllowFrameChange: false,
BaseFrame: 7,
HasImage: false, HasImage: false,
FixedWidth: 93, FixedWidth: buttonSkillTreeTabFixedWidth,
FixedHeight: 107, FixedHeight: buttonSkillTreeTabFixedHeight,
LabelColor: whiteAlpha100, LabelColor: whiteAlpha100,
}, },
} }
@ -272,15 +279,15 @@ func (ui *UIManager) NewButton(buttonType ButtonType, text string) *Button {
if buttonLayout.FixedWidth > 0 { if buttonLayout.FixedWidth > 0 {
btn.width = buttonLayout.FixedWidth btn.width = buttonLayout.FixedWidth
} else { } else {
for i := 0; i < buttonLayout.XSegments; i++ { for i := 0; i < buttonLayout.XSegments; i++ {
w, _, err := buttonSprite.GetFrameSize(i) w, _, err := buttonSprite.GetFrameSize(i)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
return nil return nil
} }
btn.width += w btn.width += w
} }
} }
if buttonLayout.FixedHeight > 0 { if buttonLayout.FixedHeight > 0 {

View File

@ -59,6 +59,10 @@ const (
optAutomapShowNames optAutomapShowNames
) )
const (
singleFrame = time.Millisecond * 16
)
// EscapeMenu represents the in-game menu that shows up when the esc key is pressed // EscapeMenu represents the in-game menu that shows up when the esc key is pressed
type EscapeMenu struct { type EscapeMenu struct {
isOpen bool isOpen bool
@ -449,7 +453,7 @@ func (m *EscapeMenu) setLayout(id layoutID) {
m.rightPent.SetVisible(false) m.rightPent.SetVisible(false)
go func() { go func() {
time.Sleep(16 * time.Millisecond) time.Sleep(singleFrame)
m.onHoverElement(m.layouts[id].currentEl) m.onHoverElement(m.layouts[id].currentEl)
m.leftPent.SetVisible(true) m.leftPent.SetVisible(true)
m.rightPent.SetVisible(true) m.rightPent.SetVisible(true)

View File

@ -16,13 +16,13 @@ import (
) )
const ( const (
tlCornerFrame = iota frameTopLeft = iota
lFrame frameBottomLeft
tFrameLHalf frameTopMiddleLeft
tFrameRHalf frameTopMiddleRight
trCornerFrameTHalf frameTopRightNoCorner
trCornerFrameRHalf frameTopRight
rFrame frameBottomRight
) )
const ( const (
@ -34,9 +34,10 @@ const (
windowWidth = 800 windowWidth = 800
bulletOffsetY = 14 bulletOffsetY = 14
lineOffset = 5
// the title of the panel // the title of the panel
titleLabelOffsetX = -30 titleLabelOffsetX = -37
// for the bulleted list near the top of the screen // for the bulleted list near the top of the screen
listRootX = 100 listRootX = 100
@ -48,8 +49,10 @@ const (
listBulletX = listRootX - listBulletOffsetX listBulletX = listRootX - listBulletOffsetX
// the close button for the help panel // the close button for the help panel
closeButtonX = 685 closeButtonX = 685
closeButtonY = 25 closeButtonY = 25
closeButtonLabelX = 680
closeButtonLabelY = 60
// the rest of these are for text with a line and dot, towards the bottom of the screen // the rest of these are for text with a line and dot, towards the bottom of the screen
newStatsLabelX = 222 newStatsLabelX = 222
@ -217,14 +220,42 @@ func (h *Overlay) IsInRect(px, py int) bool {
// Load the overlay graphical assets // Load the overlay graphical assets
func (h *Overlay) Load() { func (h *Overlay) Load() {
var ( /*
x = 0 the 800x600 help screen dc6 file frames look like this
y = 0 the position we set for frames is the lower-left corner x,y
prevX = 0 +----+------------------+-------------------+------------+----+
prevY = 0 | 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) f, err := h.uiManager.NewSprite(d2resource.HelpBorder, d2resource.PaletteSky)
if err != nil { if err != nil {
log.Print(err) log.Print(err)
@ -235,38 +266,36 @@ func (h *Overlay) Load() {
log.Print(err) log.Print(err)
} }
ww, hh := f.GetCurrentFrameSize() frameWidth, frameHeight := f.GetCurrentFrameSize()
//fmt.Printf("Help frame %d size: %d, %d\n", frameIndex, ww, hh)
switch frameIndex { switch frameIndex {
case tlCornerFrame: case frameTopLeft:
y = hh currentY += frameHeight
case lFrame: firstFrameWidth = frameWidth
y = hh + prevY case frameBottomLeft:
case tFrameLHalf: currentY += frameHeight
y = hh case frameTopMiddleLeft:
x = 65 currentX = firstFrameWidth
case tFrameRHalf: currentY = top + frameHeight
y = hh case frameTopMiddleRight:
x = windowWidth - ww - 245 currentY = top + frameHeight
case trCornerFrameTHalf: currentX += prevWidth
y = hh currentX += magicHelpBorderOffsetX
x = windowWidth - ww - 20 case frameTopRightNoCorner:
case trCornerFrameRHalf: currentY = top + frameHeight
y = hh currentX += prevWidth
x = windowWidth - ww case frameTopRight:
case rFrame: currentY = top + frameHeight
y = hh + prevY currentX += prevWidth
x = windowWidth - ww 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) h.frames = append(h.frames, f)
} }
@ -290,7 +319,7 @@ func (h *Overlay) Load() {
newLabel = h.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky) newLabel = h.uiManager.NewLabel(d2resource.Font16, d2resource.PaletteSky)
newLabel.SetText(d2tbl.TranslateString("strClose")) // "Close" newLabel.SetText(d2tbl.TranslateString("strClose")) // "Close"
newLabel.SetPosition(680, 60) newLabel.SetPosition(closeButtonLabelX, closeButtonLabelY)
h.text = append(h.text, newLabel) h.text = append(h.text, newLabel)
// Bullets // Bullets
@ -301,6 +330,7 @@ func (h *Overlay) Load() {
// TODO "Alt" should be hotkey // "Hold down <%s> to highlight items on the ground" // TODO "Alt" should be hotkey // "Hold down <%s> to highlight items on the ground"
{text: fmt.Sprintf(d2tbl.TranslateString("StrHelp3"), "Alt")}, {text: fmt.Sprintf(d2tbl.TranslateString("StrHelp3"), "Alt")},
// TODO "Shift" should be hotkey // "Hold down <%s> to attack while standing still" // TODO "Shift" should be hotkey // "Hold down <%s> to attack while standing still"
{text: fmt.Sprintf(d2tbl.TranslateString("StrHelp4"), "Shift")}, {text: fmt.Sprintf(d2tbl.TranslateString("StrHelp4"), "Shift")},
@ -536,9 +566,9 @@ func (h *Overlay) createCallout(c callout) {
l := line{ l := line{
StartX: c.LabelX, StartX: c.LabelX,
StartY: c.LabelY + hh + 5, StartY: c.LabelY + hh + lineOffset,
MoveX: 0, MoveX: 0,
MoveY: c.DotY - c.LabelY - hh - 5, MoveY: c.DotY - c.LabelY - hh - lineOffset,
Color: color.White, Color: color.White,
} }