1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-09-29 22:56:07 -04:00

Add inventory.txt loader, use the records (#573)

* adding resource entry for inventory.txt

* adding loader for inventory.txt

* adding call to inventory.txt loader in d2app

* d2game now uses the inventory.txt records for making the inventory panel
This commit is contained in:
dk 2020-07-11 08:25:34 -07:00 committed by GitHub
parent d85e2bdd51
commit 3aab0515cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 88 deletions

View File

@ -234,6 +234,7 @@ func (p *App) loadDataDict() error {
{d2resource.LevelSubstitutions, d2datadict.LoadLevelSubstitutions},
{d2resource.CubeRecipes, d2datadict.LoadCubeRecipes},
{d2resource.SuperUniques, d2datadict.LoadSuperUniques},
{d2resource.Inventory, d2datadict.LoadInventory},
}
d2datadict.InitObjectRecords()

View File

@ -0,0 +1,160 @@
package d2datadict
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"log"
)
type box struct {
Left int
Right int
Top int
Bottom int
Width int
Height int
}
type grid struct {
Box *box
Rows int
Columns int
CellWidth int
CellHeight int
}
type InventoryRecord struct {
Name string
Panel *box
Grid *grid
Slots map[d2enum.EquippedSlot]*box
}
var Inventory map[string]*InventoryRecord
func LoadInventory(file []byte) {
d := d2common.LoadDataDictionary(file)
Inventory = make(map[string]*InventoryRecord, 0)
for d.Next() {
// we need to calc the width/height for the box as it isn't
// specified in the txt file
pBox := &box{}
pBox.Left = d.Number("invLeft")
pBox.Right = d.Number("invRight")
pBox.Top = d.Number("invTop")
pBox.Bottom = d.Number("invBottom")
pBox.Width = pBox.Right - pBox.Left
pBox.Height = pBox.Bottom - pBox.Top
gBox := &box{
Left: d.Number("gridLeft"),
Right: d.Number("gridRight"),
Top: d.Number("gridTop"),
Bottom: d.Number("gridBottom"),
}
gBox.Width = gBox.Right - gBox.Left
gBox.Height = gBox.Bottom - gBox.Top
record := &InventoryRecord{
Name: d.String("class"),
Panel: pBox,
Grid: &grid{
Box: gBox,
Rows: d.Number("gridY"),
Columns: d.Number("gridX"),
CellWidth: d.Number("gridBoxWidth"),
CellHeight: d.Number("gridBoxHeight"),
},
Slots: map[d2enum.EquippedSlot]*box{
d2enum.EquippedSlotHead: {
d.Number("headLeft"),
d.Number("headRight"),
d.Number("headTop"),
d.Number("headBottom"),
d.Number("headWidth"),
d.Number("headHeight"),
},
d2enum.EquippedSlotNeck: {
d.Number("neckLeft"),
d.Number("neckRight"),
d.Number("neckTop"),
d.Number("neckBottom"),
d.Number("neckWidth"),
d.Number("neckHeight"),
},
d2enum.EquippedSlotTorso: {
d.Number("torsoLeft"),
d.Number("torsoRight"),
d.Number("torsoTop"),
d.Number("torsoBottom"),
d.Number("torsoWidth"),
d.Number("torsoHeight"),
},
d2enum.EquippedSlotLeftArm: {
d.Number("lArmLeft"),
d.Number("lArmRight"),
d.Number("lArmTop"),
d.Number("lArmBottom"),
d.Number("lArmWidth"),
d.Number("lArmHeight"),
},
d2enum.EquippedSlotRightArm: {
d.Number("rArmLeft"),
d.Number("rArmRight"),
d.Number("rArmTop"),
d.Number("rArmBottom"),
d.Number("rArmWidth"),
d.Number("rArmHeight"),
},
d2enum.EquippedSlotLeftHand: {
d.Number("lHandLeft"),
d.Number("lHandRight"),
d.Number("lHandTop"),
d.Number("lHandBottom"),
d.Number("lHandWidth"),
d.Number("lHandHeight"),
},
d2enum.EquippedSlotRightHand: {
d.Number("rHandLeft"),
d.Number("rHandRight"),
d.Number("rHandTop"),
d.Number("rHandBottom"),
d.Number("rHandWidth"),
d.Number("rHandHeight"),
},
d2enum.EquippedSlotGloves: {
d.Number("glovesLeft"),
d.Number("glovesRight"),
d.Number("glovesTop"),
d.Number("glovesBottom"),
d.Number("glovesWidth"),
d.Number("glovesHeight"),
},
d2enum.EquippedSlotBelt: {
d.Number("beltLeft"),
d.Number("beltRight"),
d.Number("beltTop"),
d.Number("beltBottom"),
d.Number("beltWidth"),
d.Number("beltHeight"),
},
d2enum.EquippedSlotLegs: {
d.Number("feetLeft"),
d.Number("feetRight"),
d.Number("feetTop"),
d.Number("feetBottom"),
d.Number("feetWidth"),
d.Number("feetHeight"),
},
},
}
Inventory[record.Name] = record
}
if d.Err != nil {
panic(d.Err)
}
log.Printf("Loaded %d Inventory Panel records", len(Inventory))
}

View File

@ -196,6 +196,7 @@ const (
// --- Inventory Data ---
Inventory = "/data/global/excel/inventory.txt"
Weapons = "/data/global/excel/weapons.txt"
Armor = "/data/global/excel/armor.txt"
Misc = "/data/global/excel/misc.txt"

View File

@ -1,6 +1,9 @@
package d2player
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
)
// EquipmentSlot represents an equipment slot for a player
type EquipmentSlot struct {
@ -11,78 +14,33 @@ type EquipmentSlot struct {
height int
}
//nolint:gomnd Magic numbers are necessary for this file
func genEquipmentSlotsMap() map[d2enum.EquippedSlot]EquipmentSlot {
return map[d2enum.EquippedSlot]EquipmentSlot{
d2enum.EquippedSlotLeftArm: {
item: nil,
x: 418,
y: 224,
width: 61,
height: 116,
},
d2enum.EquippedSlotRightArm: {
item: nil,
x: 648,
y: 224,
width: 61,
height: 116,
},
d2enum.EquippedSlotHead: {
item: nil,
x: 532,
y: 125,
width: 62,
height: 62,
},
d2enum.EquippedSlotNeck: {
item: nil,
x: 604,
y: 125,
width: 32,
height: 32,
},
d2enum.EquippedSlotTorso: {
item: nil,
x: 532,
y: 224,
width: 62,
height: 90,
},
d2enum.EquippedSlotBelt: {
item: nil,
x: 533,
y: 269,
width: 62,
height: 32,
},
d2enum.EquippedSlotLeftHand: {
item: nil,
x: 491,
y: 270,
width: 32,
height: 32,
},
d2enum.EquippedSlotRightHand: {
item: nil,
x: 606,
y: 270,
width: 32,
height: 32,
},
d2enum.EquippedSlotGloves: {
item: nil,
x: 417,
y: 299,
width: 62,
height: 62,
},
d2enum.EquippedSlotLegs: {
item: nil,
x: 648,
y: 299,
width: 62,
height: 62,
},
func genEquipmentSlotsMap(record *d2datadict.InventoryRecord) map[d2enum.EquippedSlot]EquipmentSlot {
slotMap := map[d2enum.EquippedSlot]EquipmentSlot{}
slots := []d2enum.EquippedSlot{
d2enum.EquippedSlotHead,
d2enum.EquippedSlotTorso,
d2enum.EquippedSlotLegs,
d2enum.EquippedSlotRightArm,
d2enum.EquippedSlotLeftArm,
d2enum.EquippedSlotLeftHand,
d2enum.EquippedSlotRightHand,
d2enum.EquippedSlotNeck,
d2enum.EquippedSlotBelt,
d2enum.EquippedSlotGloves,
}
for _, slot := range slots {
box := record.Slots[slot]
equipmentSlot := EquipmentSlot{
nil,
box.Left,
box.Bottom + cellPadding,
box.Width,
box.Height,
}
slotMap[slot] = equipmentSlot
}
return slotMap
}

View File

@ -1,6 +1,7 @@
package d2player
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
"image"
"image/color"
@ -96,13 +97,36 @@ func NewGameControls(renderer d2interface.Renderer, hero *d2mapentity.Player, ma
nameLabel.SetText("")
nameLabel.Color = color.White
// TODO make this depend on the hero type to respect inventory.txt
var inventoryRecordKey string
switch hero.Class {
case d2enum.HeroAssassin:
inventoryRecordKey = "Assassin"
case d2enum.HeroAmazon:
inventoryRecordKey = "Amazon2"
case d2enum.HeroBarbarian:
inventoryRecordKey = "Barbarian2"
case d2enum.HeroDruid:
inventoryRecordKey = "Druid"
case d2enum.HeroNecromancer:
inventoryRecordKey = "Necromancer2"
case d2enum.HeroPaladin:
inventoryRecordKey = "Paladin2"
case d2enum.HeroSorceress:
inventoryRecordKey = "Sorceress2"
default:
inventoryRecordKey = "Amazon2"
}
inventoryRecord := d2datadict.Inventory[inventoryRecordKey]
gc := &GameControls{
renderer: renderer,
hero: hero,
mapEngine: mapEngine,
inputListener: inputListener,
mapRenderer: mapRenderer,
inventory: NewInventory(),
inventory: NewInventory(inventoryRecord),
heroStatsPanel: NewHeroStatsPanel(renderer, hero.Name(), hero.Class, hero.Stats),
nameLabel: &nameLabel,
zoneChangeText: &zoneLabel,

View File

@ -1,6 +1,7 @@
package d2player
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
@ -18,13 +19,12 @@ type Inventory struct {
isOpen bool
}
func NewInventory() *Inventory {
originX := 400
originY := 0
func NewInventory(record *d2datadict.InventoryRecord) *Inventory {
return &Inventory{
grid: NewItemGrid(10, 4, originX+19, originY+320),
originX: originX,
originY: originY,
grid: NewItemGrid(record),
originX: record.Panel.Left,
// originY: record.Panel.Top,
originY: 0, // expansion data has these all offset by +60 ...
}
}

View File

@ -3,6 +3,7 @@ package d2player
import (
"errors"
"fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -14,6 +15,11 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
)
// images for 1x1 grid tile items (rings and stuff) are 28x28 pixel
// however, the grid cells are 29x29 pixels, this is for padding
// for each row in inventory, we need to account for this padding
const cellPadding = 1
type InventoryItem interface {
InventoryGridSize() (width int, height int)
GetItemCode() string
@ -36,15 +42,16 @@ type ItemGrid struct {
slotSize int
}
func NewItemGrid(width int, height int, originX int, originY int) *ItemGrid {
func NewItemGrid(record *d2datadict.InventoryRecord) *ItemGrid {
grid := record.Grid
return &ItemGrid{
width: width,
height: height,
originX: originX,
originY: originY,
slotSize: 29,
width: grid.Box.Width,
height: grid.Box.Height,
originX: grid.Box.Left,
originY: grid.Box.Top + (grid.Rows * cellPadding),
slotSize: grid.CellWidth,
sprites: make(map[string]*d2ui.Sprite),
equipmentSlots: genEquipmentSlotsMap(),
equipmentSlots: genEquipmentSlotsMap(record),
}
}