OpenDiablo2/d2common/d2data/d2datadict/set_items.go

204 lines
7.1 KiB
Go

package d2datadict
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
const (
numPropertiesOnSetItem = 9
numBonusPropertiesOnSetItem = 5
bonusToken1 = "a"
bonusToken2 = "b"
propCodeFmt = "prop%d"
propParamFmt = "par%d"
propMinFmt = "min%d"
propMaxFmt = "max%d"
bonusCodeFmt = "aprop%d%s"
bonusParamFmt = "apar%d%s"
bonusMinFmt = "amin%d%s"
bonusMaxFmt = "amax%d%s"
)
// SetItemRecord represents a set item
type SetItemRecord struct {
// SetItemKey (index)
// string key to item's name in a .tbl file
SetItemKey string
// SetKey (set)
// string key to the index field in Sets.txt - the set the item is a part of.
SetKey string
// ItemCode (item)
// base item code of this set item (matches code field in Weapons.txt, Armor.txt or Misc.txt files).
ItemCode string
// Rarity
// Chance to pick this set item if more then one set item of the same base item exist,
// this uses the common rarity/total_rarity formula, so if you have two set rings,
// one with a rarity of 100 the other with a rarity of 1,
// then the first will drop 100/101 percent of the time (
// 99%) and the other will drop 1/101 percent of the time (1%),
// rarity can be anything between 0 and 255.
Rarity int
// QualityLevel (lvl)
// The quality level of this set item, monsters, cube recipes, vendors,
// objects and the like most be at least this level or higher to be able to drop this item,
// otherwise they would drop a magical item with twice normal durability.
QualityLevel int
// RequiredLevel ("lvl req")
// The character level required to use this set item.
RequiredLevel int
// CharacterPaletteTransform (chrtransform)
// Palette shift to apply to the the DCC component-file and the DC6 flippy-file (
// whenever or not the color shift will apply is determined by Weapons.txt,
// Armor.txt or Misc.txt). This is an ID pointer from Colors.txt.
CharacterPaletteTransform int
// InventoryPaletteTransform (invtransform)
// Palette shift to apply to the the DC6 inventory-file (
// whenever or not the color shift will apply is determined by Weapons.txt,
// Armor.txt or Misc.txt). This is an ID pointer from Colors.txt.
InventoryPaletteTransform int
// InvFile
// Overrides the invfile and setinvfile specified in Weapons.txt,
// Armor.txt or Misc.txt for the base item.
// This field contains the file name of the DC6 inventory graphic (without the .dc6 extension).
InvFile string
// FlippyFile
// Overrides the flippyfile specified in Weapons.txt, Armor.txt or Misc.txt for the base item.
// This field contains the file name of the DC6 flippy animation (without the .dc6 extension).
FlippyFile string
// DropSound
// Overrides the dropsound (the sound played when the item hits the ground) specified in Weapons.
// txt, Armor.txt or Misc.txt for the base item. This field contains an ID pointer from Sounds.txt.
DropSound string
// DropSfxFrame
// How many frames after the flippy animation starts playing will the associated drop sound start
// to play. This overrides the values in Weapons.txt, Armor.txt or Misc.txt.
DropSfxFrame int
// UseSound
// Overrides the usesound (the sound played when the item is consumed by the player) specified in
// Weapons.txt, Armor.txt or Misc.txt for the base item.
// This field contains an ID pointer from Sounds.txt.
UseSound string
// CostMult ("cost mult")
// The base item's price is multiplied by this value when sold, repaired or bought from a vendor.
CostMult int
// CostAdd ("cost add")
// After the price has been multiplied, this amount of gold is added to the price on top.
CostAdd int
// AddFn ("add func")
// a property mode field that controls how the variable attributes will appear and be functional
// on a set item. See the appendix for further details about this field's effects.
AddFn int
// Properties are a propert code, parameter, min, max for generating an item propert
Properties [numPropertiesOnSetItem]*SetItemProperty
// SetPropertiesLevel1 is the first version of bonus properties for the set
SetPropertiesLevel1 [numBonusPropertiesOnSetItem]*SetItemProperty
// SetPropertiesLevel2 is the second version of bonus properties for the set
SetPropertiesLevel2 [numBonusPropertiesOnSetItem]*SetItemProperty
}
// SetItemProperty is describes a property of a set item
type SetItemProperty struct {
Code string
Parameter string // depending on the property, this may be an int (usually), or a string
Min int
Max int
}
// SetItems holds all of the SetItemRecords
var SetItems map[string]*SetItemRecord //nolint:gochecknoglobals // Currently global by design,
// only written once
// LoadSetItems loads all of the SetItemRecords from SetItems.txt
func LoadSetItems(file []byte) {
SetItems = make(map[string]*SetItemRecord)
d := d2txt.LoadDataDictionary(file)
for d.Next() {
record := &SetItemRecord{
SetItemKey: d.String("index"),
SetKey: d.String("set"),
ItemCode: d.String("item"),
Rarity: d.Number("rarity"),
QualityLevel: d.Number("lvl"),
RequiredLevel: d.Number("lvl req"),
CharacterPaletteTransform: d.Number("chrtransform"),
InventoryPaletteTransform: d.Number("invtransform"),
InvFile: d.String("invfile"),
FlippyFile: d.String("flippyfile"),
DropSound: d.String("dropsound"),
DropSfxFrame: d.Number("dropsfxframe"),
UseSound: d.String("usesound"),
CostMult: d.Number("cost mult"),
CostAdd: d.Number("cost add"),
AddFn: d.Number("add func"),
}
// normal properties
props := [numPropertiesOnSetItem]*SetItemProperty{}
for idx := 0; idx < numPropertiesOnSetItem; idx++ {
num := idx + 1
props[idx] = &SetItemProperty{
d.String(fmt.Sprintf(propCodeFmt, num)),
d.String(fmt.Sprintf(propParamFmt, num)),
d.Number(fmt.Sprintf(propMinFmt, num)),
d.Number(fmt.Sprintf(propMaxFmt, num)),
}
}
// set bonus properties
bonus1 := [numBonusPropertiesOnSetItem]*SetItemProperty{}
bonus2 := [numBonusPropertiesOnSetItem]*SetItemProperty{}
for idx := 0; idx < numBonusPropertiesOnSetItem; idx++ {
num := idx + 1
bonus1[idx] = &SetItemProperty{
d.String(fmt.Sprintf(bonusCodeFmt, num, bonusToken1)),
d.String(fmt.Sprintf(bonusParamFmt, num, bonusToken1)),
d.Number(fmt.Sprintf(bonusMinFmt, num, bonusToken1)),
d.Number(fmt.Sprintf(bonusMaxFmt, num, bonusToken1)),
}
bonus2[idx] = &SetItemProperty{
d.String(fmt.Sprintf(bonusCodeFmt, num, bonusToken2)),
d.String(fmt.Sprintf(bonusParamFmt, num, bonusToken2)),
d.Number(fmt.Sprintf(bonusMinFmt, num, bonusToken2)),
d.Number(fmt.Sprintf(bonusMaxFmt, num, bonusToken2)),
}
}
record.Properties = props
SetItems[record.SetItemKey] = record
}
if d.Err != nil {
panic(d.Err)
}
log.Printf("Loaded %d SetItem records", len(SetItems))
}