2020-07-24 21:56:19 -04:00
|
|
|
package d2datadict
|
|
|
|
|
|
|
|
import (
|
2020-08-04 11:16:06 -04:00
|
|
|
"fmt"
|
2020-07-24 21:56:19 -04:00
|
|
|
"log"
|
|
|
|
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
|
|
)
|
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
const (
|
|
|
|
numPartialSetProperties = 4
|
|
|
|
numFullSetProperties = 8
|
|
|
|
fmtPropCode = "%sCode%d%s"
|
|
|
|
fmtPropParam = "%sParam%d%s"
|
|
|
|
fmtPropMin = "%sMin%d%s"
|
|
|
|
fmtPropMax = "%sMax%d%s"
|
|
|
|
partialIdxOffset = 2
|
|
|
|
setPartialToken = "P"
|
|
|
|
setPartialTokenA = "a"
|
|
|
|
setPartialTokenB = "b"
|
|
|
|
setFullToken = "F"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SetRecord describes the set bonus for a group of set items
|
2020-07-24 21:56:19 -04:00
|
|
|
type SetRecord struct {
|
|
|
|
// index
|
|
|
|
// String key linked to by the set field in SetItems.
|
|
|
|
// txt - used to tie all of the set's items to the same set.
|
|
|
|
Key string
|
|
|
|
|
|
|
|
// name
|
|
|
|
// String key to item's name in a .tbl file.
|
|
|
|
StringTableKey string
|
|
|
|
|
|
|
|
// Version 0 for vanilla, 100 for LoD expansion
|
|
|
|
Version int
|
|
|
|
|
|
|
|
// Level
|
|
|
|
// set level, perhaps intended as a minimum level for partial or full attributes to appear
|
|
|
|
// (reference only, not loaded into game).
|
|
|
|
Level int
|
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
// Properties contains the partial and full set bonus properties.
|
|
|
|
Properties struct {
|
|
|
|
PartialA []*setProperty
|
|
|
|
PartialB []*setProperty
|
|
|
|
Full []*setProperty
|
|
|
|
}
|
|
|
|
}
|
2020-07-24 21:56:19 -04:00
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
type setProperty struct {
|
|
|
|
// Code is an ID pointer of a property from Properties.txt,
|
2020-07-24 21:56:19 -04:00
|
|
|
// these columns control each of the eight different full set modifiers a set item can grant you
|
|
|
|
// at most.
|
2020-08-04 11:16:06 -04:00
|
|
|
Code string
|
2020-07-24 21:56:19 -04:00
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
// Param is the passed on to the associated property, this is used to pass skill IDs, state IDs,
|
2020-07-24 21:56:19 -04:00
|
|
|
// monster IDs, montype IDs and the like on to the properties that require them,
|
|
|
|
// these fields support calculations.
|
2020-08-04 11:16:06 -04:00
|
|
|
Param string
|
2020-07-24 21:56:19 -04:00
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
// Min value to assign to the associated property.
|
2020-07-24 21:56:19 -04:00
|
|
|
// Certain properties have special interpretations based on stat encoding (e.g.
|
|
|
|
// chance-to-cast and charged skills). See the File Guides for Properties.txt and ItemStatCost.
|
|
|
|
// txt for further details.
|
2020-08-04 11:16:06 -04:00
|
|
|
Min int
|
2020-07-24 21:56:19 -04:00
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
// Max value to assign to the associated property.
|
2020-07-24 21:56:19 -04:00
|
|
|
// Certain properties have special interpretations based on stat encoding (e.g.
|
|
|
|
// chance-to-cast and charged skills). See the File Guides for Properties.txt and ItemStatCost.
|
|
|
|
// txt for further details.
|
2020-08-04 11:16:06 -04:00
|
|
|
Max int
|
2020-07-24 21:56:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetRecords contain the set records from sets.txt
|
2020-08-04 11:16:06 -04:00
|
|
|
var SetRecords map[string]*SetRecord //nolint:gochecknoglobals // Currently global by design
|
2020-07-24 21:56:19 -04:00
|
|
|
|
|
|
|
// LoadSetRecords loads set records from sets.txt
|
2020-08-04 11:16:06 -04:00
|
|
|
func LoadSetRecords(file []byte) { //nolint:funlen // doesn't make sense to split
|
2020-07-24 21:56:19 -04:00
|
|
|
SetRecords = make(map[string]*SetRecord)
|
|
|
|
|
|
|
|
d := d2common.LoadDataDictionary(file)
|
|
|
|
for d.Next() {
|
|
|
|
record := &SetRecord{
|
|
|
|
Key: d.String("index"),
|
|
|
|
StringTableKey: d.String("name"),
|
|
|
|
Version: d.Number("version"),
|
|
|
|
Level: d.Number("level"),
|
2020-08-04 11:16:06 -04:00
|
|
|
Properties: struct {
|
|
|
|
PartialA []*setProperty
|
|
|
|
PartialB []*setProperty
|
|
|
|
Full []*setProperty
|
|
|
|
}{
|
|
|
|
PartialA: make([]*setProperty, 0),
|
|
|
|
PartialB: make([]*setProperty, 0),
|
|
|
|
Full: make([]*setProperty, 0),
|
2020-07-24 21:56:19 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-08-04 11:16:06 -04:00
|
|
|
// for partial properties 2a thru 5b
|
|
|
|
for idx := 0; idx < numPartialSetProperties; idx++ {
|
|
|
|
num := idx + partialIdxOffset // needs to be 2,3,4,5
|
|
|
|
columnA := fmt.Sprintf(fmtPropCode, setPartialToken, num, setPartialTokenA)
|
|
|
|
columnB := fmt.Sprintf(fmtPropCode, setPartialToken, num, setPartialTokenB)
|
|
|
|
|
|
|
|
if codeA := d.String(columnA); codeA != "" {
|
|
|
|
paramColumn := fmt.Sprintf(fmtPropParam, setPartialToken, num, setPartialTokenA)
|
|
|
|
minColumn := fmt.Sprintf(fmtPropMin, setPartialToken, num, setPartialTokenA)
|
|
|
|
maxColumn := fmt.Sprintf(fmtPropMax, setPartialToken, num, setPartialTokenA)
|
|
|
|
|
|
|
|
propA := &setProperty{
|
|
|
|
Code: codeA,
|
|
|
|
Param: d.String(paramColumn),
|
|
|
|
Min: d.Number(minColumn),
|
|
|
|
Max: d.Number(maxColumn),
|
|
|
|
}
|
|
|
|
|
|
|
|
record.Properties.PartialA = append(record.Properties.PartialA, propA)
|
|
|
|
}
|
|
|
|
|
|
|
|
if codeB := d.String(columnB); codeB != "" {
|
|
|
|
paramColumn := fmt.Sprintf(fmtPropParam, setPartialToken, num, setPartialTokenB)
|
|
|
|
minColumn := fmt.Sprintf(fmtPropMin, setPartialToken, num, setPartialTokenB)
|
|
|
|
maxColumn := fmt.Sprintf(fmtPropMax, setPartialToken, num, setPartialTokenB)
|
|
|
|
|
|
|
|
propB := &setProperty{
|
|
|
|
Code: codeB,
|
|
|
|
Param: d.String(paramColumn),
|
|
|
|
Min: d.Number(minColumn),
|
|
|
|
Max: d.Number(maxColumn),
|
|
|
|
}
|
|
|
|
|
|
|
|
record.Properties.PartialB = append(record.Properties.PartialB, propB)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for idx := 0; idx < numFullSetProperties; idx++ {
|
|
|
|
num := idx + 1
|
|
|
|
codeColumn := fmt.Sprintf(fmtPropCode, setFullToken, num, "")
|
|
|
|
paramColumn := fmt.Sprintf(fmtPropParam, setFullToken, num, "")
|
|
|
|
minColumn := fmt.Sprintf(fmtPropMin, setFullToken, num, "")
|
|
|
|
maxColumn := fmt.Sprintf(fmtPropMax, setFullToken, num, "")
|
|
|
|
|
|
|
|
if code := d.String(codeColumn); code != "" {
|
|
|
|
prop := &setProperty{
|
|
|
|
Code: code,
|
|
|
|
Param: d.String(paramColumn),
|
|
|
|
Min: d.Number(minColumn),
|
|
|
|
Max: d.Number(maxColumn),
|
|
|
|
}
|
|
|
|
|
|
|
|
record.Properties.Full = append(record.Properties.Full, prop)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-24 21:56:19 -04:00
|
|
|
SetRecords[record.Key] = record
|
|
|
|
}
|
|
|
|
|
|
|
|
if d.Err != nil {
|
|
|
|
panic(d.Err)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("Loaded %d Sets records", len(SetRecords))
|
|
|
|
}
|