mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-06 00:26:40 -05:00
d2data item related loaders (#619)
* added loader for ItemTypes.txt * added loader for bodylocs.txt * lint fix for item_types loader * adding loader for sets.txt * minor edit * adding loader for SetItems.txt * added loader for automagic.txt
This commit is contained in:
parent
1ce81f1aec
commit
b13175b070
@ -239,6 +239,11 @@ func (a *App) loadDataDict() error {
|
||||
{d2resource.Skills, d2datadict.LoadSkills},
|
||||
{d2resource.Properties, d2datadict.LoadProperties},
|
||||
{d2resource.SkillDesc, d2datadict.LoadSkillDescriptions},
|
||||
{d2resource.ItemTypes, d2datadict.LoadItemTypes},
|
||||
{d2resource.BodyLocations, d2datadict.LoadBodyLocations},
|
||||
{d2resource.Sets, d2datadict.LoadSets},
|
||||
{d2resource.SetItems, d2datadict.LoadSetItems},
|
||||
{d2resource.AutoMagic, d2datadict.LoadAutoMagicRecords},
|
||||
}
|
||||
|
||||
d2datadict.InitObjectRecords()
|
||||
|
206
d2common/d2data/d2datadict/automagic.go
Normal file
206
d2common/d2data/d2datadict/automagic.go
Normal file
@ -0,0 +1,206 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
)
|
||||
|
||||
// AutoMagicRecord describes rules for automatically generating magic properties when spawning
|
||||
// items
|
||||
type AutoMagicRecord struct {
|
||||
// Name
|
||||
// String Comment Blizzard lists the equivalent prefix/affix here.
|
||||
// You can use what ever you wish here though. Handy for keeping track of groups.
|
||||
Name string
|
||||
|
||||
// Version
|
||||
// it needs to be set to 0 if the prefix\affix you want to create or edit is going to be a
|
||||
// classic-only item ( with "classic" we mean "non-expansion" mode,
|
||||
// which you can toggle on and off when creating a character) or set to 100 if it's going to be
|
||||
// available in Expansion. This field is important,
|
||||
// as Items with " version" set to 100 will NOT be generated in Classic Diablo II.
|
||||
Version int
|
||||
|
||||
// Spawnable
|
||||
// It is a boolean type field, and states if this autoprefix can actually spawn in the game.
|
||||
// You can disable this row by setting it to 0 , or enable it by setting it to 1
|
||||
Spawnable bool
|
||||
|
||||
// SpawnOnRare
|
||||
// It decides whether this autoprefix spawns on rare quality items or not.
|
||||
// You can prevent that from happening by setting it to 0 , or you can allow it by setting it to 1
|
||||
SpawnOnRare bool // rare
|
||||
|
||||
// MinSpawnLevel
|
||||
// this field accepts numeric values and specifies the minimum level from which this autoprefix
|
||||
// can spawn. The column in question can be combined with the following maxlevel: to effectively
|
||||
// control groups of automods,
|
||||
// because you can use this field to combine multiple rows so that the autoprefixes are assigned
|
||||
// based on the level of the treasure drop [see below].
|
||||
MinSpawnLevel int // level
|
||||
|
||||
// MaxSpawnLevel
|
||||
// this field accepts numeric values and specifies the maximum level beyond which the automod
|
||||
// stop spawning.
|
||||
MaxSpawnLevel int // maxlevel
|
||||
|
||||
// LevelRequirement
|
||||
// It is the level requirement for this autoprefix.
|
||||
// This value is added to the Level Requirement of the item generated with this mod.
|
||||
LevelRequirement int
|
||||
|
||||
// Class
|
||||
// the class type
|
||||
Class d2enum.Hero
|
||||
|
||||
// ClassLevelRequirement
|
||||
// If class is set, this should allow a separate level requirement for this class.
|
||||
// This is a polite thing to do,
|
||||
// as other classes gain no advantage from class specific modifiers.
|
||||
// I am uncertain that this actually works.
|
||||
ClassLevelRequirement int // classlevelreq
|
||||
|
||||
// Frequency
|
||||
// For autoprefix groups, it states the chance to spawn this specific group member vs others.
|
||||
// Higher numbers means the automod will be more common. The 1.
|
||||
// 09 version file guide has some formuae relateing to this.
|
||||
Frequency int
|
||||
|
||||
// Group
|
||||
// This field accepts numeric values and groups all the lines with the same values,
|
||||
// which are treated as a group. Only one autoprefix per group can be chosen,
|
||||
// and groups are influenced by levelreq, classlevelreq and frequency The 1.
|
||||
// 09 version file guide has a very nice tutorial about how to set up groups.
|
||||
// NOTE: The group number must also be entered in the 'auto prefix' column of each entry in
|
||||
// Weapons.txt or Armor.txt in order for the property to appear.
|
||||
Group int
|
||||
|
||||
// ModCode
|
||||
// They're the Property codes from Properties.txt.
|
||||
// These determine the actual properties which make up this autoprefix.
|
||||
// Each autoprefix can include up to three modifiers.
|
||||
ModCode [3]string
|
||||
|
||||
// ModParam, min, max
|
||||
// Parameter, min, and max values for the property
|
||||
ModParam [3]int
|
||||
ModMin [3]int
|
||||
ModMax [3]int
|
||||
|
||||
// transform
|
||||
// It is a boolean value whichallows the colorization of the items.
|
||||
Transform bool
|
||||
|
||||
// PaletteTransform
|
||||
// If transform is set to 1 then the item will be colored with the chosen color code,
|
||||
// taken from Colors.txt
|
||||
PaletteTransform int // transformcolor
|
||||
|
||||
// IncludeItemCodes
|
||||
// itype 1 to itype7
|
||||
// "Include Type" fields. You need to place item codes in any of these columns to allow that item
|
||||
// to receive mods from this row. See the note below.
|
||||
IncludeItemCodes [7]string
|
||||
|
||||
// ExcludeItemCodes
|
||||
// etype 1 to etype3
|
||||
// 'Exclude type' . This field prevents certain mods from spawning on specific item codes.
|
||||
ExcludeItemCodes [3]string
|
||||
|
||||
// CostDivide
|
||||
// Numeric value that acts as divisor for the item price.
|
||||
CostDivide int // divide
|
||||
|
||||
// CostMultiply
|
||||
// Numeric value that acts as multiplier for the item price.
|
||||
CostMultiply int // multiply
|
||||
|
||||
// CostAdd
|
||||
// Numeric value that acts as a flat sum added to the item price.
|
||||
CostAdd int // add
|
||||
}
|
||||
|
||||
// AutoMagic has all of the AutoMagicRecords, used for generating magic properties for spawned items
|
||||
var AutoMagic []*AutoMagicRecord //nolint:gochecknoglobals // Currently global by design, only written once
|
||||
|
||||
// LoadAutoMagicRecords loads AutoMagic records from automagic.txt
|
||||
func LoadAutoMagicRecords(file []byte) {
|
||||
AutoMagic = make([]*AutoMagicRecord, 0)
|
||||
|
||||
charCodeMap := map[string]d2enum.Hero{
|
||||
"ama": d2enum.HeroAmazon,
|
||||
"ass": d2enum.HeroAssassin,
|
||||
"bar": d2enum.HeroBarbarian,
|
||||
"dru": d2enum.HeroDruid,
|
||||
"nec": d2enum.HeroNecromancer,
|
||||
"pal": d2enum.HeroPaladin,
|
||||
"sor": d2enum.HeroSorceress,
|
||||
}
|
||||
|
||||
d := d2common.LoadDataDictionary(file)
|
||||
|
||||
for d.Next() {
|
||||
record := &AutoMagicRecord{
|
||||
Name: d.String("Name"),
|
||||
Version: d.Number("version"),
|
||||
Spawnable: d.Number("spawnable") > 0,
|
||||
SpawnOnRare: d.Number("rare") > 0,
|
||||
MinSpawnLevel: d.Number("level"),
|
||||
MaxSpawnLevel: d.Number("maxlevel"),
|
||||
LevelRequirement: d.Number("levelreq"),
|
||||
Class: charCodeMap[d.String("class")],
|
||||
ClassLevelRequirement: d.Number("classlevelreq"),
|
||||
Frequency: d.Number("frequency"),
|
||||
Group: d.Number("group"),
|
||||
ModCode: [3]string{
|
||||
d.String("mod1code"),
|
||||
d.String("mod2code"),
|
||||
d.String("mod3code"),
|
||||
},
|
||||
ModParam: [3]int{
|
||||
d.Number("mod1param"),
|
||||
d.Number("mod2param"),
|
||||
d.Number("mod3param"),
|
||||
},
|
||||
ModMin: [3]int{
|
||||
d.Number("mod1min"),
|
||||
d.Number("mod2min"),
|
||||
d.Number("mod3min"),
|
||||
},
|
||||
ModMax: [3]int{
|
||||
d.Number("mod1max"),
|
||||
d.Number("mod2max"),
|
||||
d.Number("mod3max"),
|
||||
},
|
||||
Transform: d.Number("transform") > 0,
|
||||
PaletteTransform: d.Number("transformcolor"),
|
||||
IncludeItemCodes: [7]string{
|
||||
d.String("itype1"),
|
||||
d.String("itype2"),
|
||||
d.String("itype3"),
|
||||
d.String("itype4"),
|
||||
d.String("itype5"),
|
||||
d.String("itype6"),
|
||||
d.String("itype7"),
|
||||
},
|
||||
ExcludeItemCodes: [3]string{
|
||||
d.String("etype1"),
|
||||
d.String("etype2"),
|
||||
d.String("etype3"),
|
||||
},
|
||||
CostDivide: d.Number("divide"),
|
||||
CostMultiply: d.Number("multiply"),
|
||||
CostAdd: d.Number("add"),
|
||||
}
|
||||
|
||||
AutoMagic = append(AutoMagic, record)
|
||||
}
|
||||
|
||||
if d.Err != nil {
|
||||
panic(d.Err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d AutoMagic records", len(AutoMagic))
|
||||
}
|
37
d2common/d2data/d2datadict/body_locations.go
Normal file
37
d2common/d2data/d2datadict/body_locations.go
Normal file
@ -0,0 +1,37 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
)
|
||||
|
||||
// BodyLocationRecord describes a body location that items can be equipped to
|
||||
type BodyLocationRecord struct {
|
||||
Name string
|
||||
Code string
|
||||
}
|
||||
|
||||
// BodyLocations contains the body location records
|
||||
//nolint:gochecknoglobals // Currently global by design, only written once
|
||||
var BodyLocations map[string]*BodyLocationRecord
|
||||
|
||||
// LoadBodyLocations loads body locations from
|
||||
func LoadBodyLocations(file []byte) {
|
||||
BodyLocations = make(map[string]*BodyLocationRecord)
|
||||
|
||||
d := d2common.LoadDataDictionary(file)
|
||||
for d.Next() {
|
||||
location := &BodyLocationRecord{
|
||||
Name: d.String("Name"),
|
||||
Code: d.String("Code"),
|
||||
}
|
||||
BodyLocations[location.Code] = location
|
||||
}
|
||||
|
||||
if d.Err != nil {
|
||||
panic(d.Err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d Body Location records", len(BodyLocations))
|
||||
}
|
257
d2common/d2data/d2datadict/item_types.go
Normal file
257
d2common/d2data/d2datadict/item_types.go
Normal file
@ -0,0 +1,257 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
)
|
||||
|
||||
// ItemTypeRecord describes the types for items
|
||||
type ItemTypeRecord struct {
|
||||
// Name (ItemType)
|
||||
// A comment field that contains the “internal name” of this iType,
|
||||
// you can basically enter anything you wish here,
|
||||
// but since you can add as many comment columns as you wish,
|
||||
// there is no reason to use it for another purpose .
|
||||
Name string
|
||||
|
||||
// Code
|
||||
// The ID pointer of this ItemType, this pointer is used in many txt files (armor.txt,
|
||||
// cubemain.txt, misc.txt, skills.txt, treasureclassex.txt, weapons.txt),
|
||||
// never use the same ID pointer twice,
|
||||
// the game will only use the first instance and ignore all other occurrences.
|
||||
// ID pointers are case sensitive, 3-4 chars long and can contain numbers, letters and symbols.
|
||||
Code string
|
||||
|
||||
// Equiv1-2
|
||||
// This is used to define the parent iType, note that an iType can have multiple parents (
|
||||
// as will be shown in the cladogram – link below),
|
||||
// the only thing you must avoid at all cost is creating infinite loops.
|
||||
// I haven't ever tested what happens when you create an iType loop,
|
||||
// but infinite loops are something you should always avoid.
|
||||
Equiv1 string
|
||||
Equiv2 string
|
||||
|
||||
// Repair
|
||||
// Boolean, 1=Merchants can repair this item type, 0=Merchants cannot repair this iType (note,
|
||||
// this also refers to charges being rechargeable).
|
||||
Repair bool
|
||||
|
||||
// Body
|
||||
// Boolean, 1=The character can wear this iType,
|
||||
// 0=This iType can only be carried in the inventory,
|
||||
// cube or stash (and belt if it is set as “beltable” in the other item related txt files)
|
||||
Body bool
|
||||
|
||||
// BodyLoc1-2
|
||||
// If you have set the previous column to 1,
|
||||
// you need to specify the inventory slots in which the item has to be equipped. (
|
||||
// the codes used by this field are read from BodyLocs.txt)
|
||||
BodyLoc1 int
|
||||
BodyLoc2 int
|
||||
|
||||
// Shoots
|
||||
// This column specifies which type of quiver (“ammo”) this iType (
|
||||
// in case it is a weapon) requires in order to shoot (
|
||||
// you use the ID pointer of the quiver iType here).
|
||||
// Caution: The place it checks which missile to pick (either arrow, bolt,
|
||||
// explosive arrow or magic arrow) is buried deep within D2Common.dll,
|
||||
// the section can be modified, there is an extensive post discussing this in Code Editing.
|
||||
// - Thanks go to Kingpin for spotting a silly little mistake in here.
|
||||
Shoots string
|
||||
|
||||
// Quiver
|
||||
// The equivalent to the previous column,
|
||||
// in here you specify which weapon this quiver is linked to. Make sure the two columns match. (
|
||||
// this also uses the ID pointer of course).
|
||||
Quiver string
|
||||
|
||||
// Throwable
|
||||
// Can this iType be thrown (determines whenever it uses the quantity and throwing damage columns
|
||||
// in Weapons.txt for example).
|
||||
Throwable bool
|
||||
|
||||
// Reload
|
||||
// Can the this item be re-stacked via drag and drop. 1=Yes, 0=No.
|
||||
Reload bool
|
||||
|
||||
// ReEquip
|
||||
// If the ammo runs out the game will automatically pick the next item of the same iType to
|
||||
// be equipped in it's place.
|
||||
// 1=Yes, 0=No. (more clearly, when you use up all the arrows in a quiver, the next quiver,
|
||||
// if available, will be equipped in its place).
|
||||
ReEquip bool
|
||||
|
||||
// AutoStack
|
||||
// Are identical stacks automatically combined when you pick the up? 1=Yes, 0=No. (for example,
|
||||
// which you pick up throwing potions or normal javelins,
|
||||
// they are automatically combined with those you already have)
|
||||
AutoStack bool
|
||||
|
||||
// Magic
|
||||
// Is this iType always Magic? 1=Yes, 0=No.
|
||||
Magic bool
|
||||
|
||||
// Rare
|
||||
// Can this iType spawn as a rare item?
|
||||
// 1=Yes, 0=No.
|
||||
// Note: If you want an item that spawns only as magic or rare,
|
||||
// you need to set the previous column to 1 as well.
|
||||
Rare bool
|
||||
|
||||
// Normal
|
||||
// Is this iType always Normal? 1=Yes, 0=No.
|
||||
Normal bool
|
||||
|
||||
// Charm
|
||||
// Does this iType function as a charm? 1=Yes, 0=No. Note: This effect is hardcoded,
|
||||
// if you need a new charm type, you must use the char iType in one of the equivs.
|
||||
Charm bool
|
||||
|
||||
// Gem
|
||||
// Can this iType be inserted into sockets? 1=Yes,
|
||||
// 0=No (Link your item to the sock iType instead to achieve this).
|
||||
Gem bool
|
||||
|
||||
// Beltable
|
||||
// Can this iType be placed in your characters belt slots? 1=Yes,
|
||||
// 0=No. (This requires further tweaking in other txt files).
|
||||
Beltable bool
|
||||
|
||||
// MaxSock1, MaxSock25, MaxSock40
|
||||
// Maximum sockets for iLvl 1-25,
|
||||
// 26-40 and 40+. The range is hardcoded but the location is known,
|
||||
// so you can alter around the range to your liking. On normal,
|
||||
// items dropped from monsters are limited to 3, on nightmare to 4 and on hell to 6 sockets,
|
||||
// irregardless of this columns content.
|
||||
MaxSock1 int
|
||||
MaxSock25 int
|
||||
MaxSock40 int
|
||||
|
||||
// TreasureClass
|
||||
// Can this iType ID Pointer be used as an auto TC in TreasureClassEx.txt. 1=Yes,
|
||||
// 0=No. *Such as armo3-99 and weap3-99 etc.
|
||||
TreasureClass int
|
||||
|
||||
// Rarity
|
||||
// Dunno what it does, may have to do with the chance that an armor or weapon rack will pick
|
||||
// items of this iType. If it works like other rarity fields,
|
||||
// the chance is rarity / total_rarity * 100.
|
||||
Rarity int
|
||||
|
||||
// StaffMods
|
||||
// Contains the class code for the character class that should get +skills from this iType (
|
||||
// such as wands that can spawn with +Necromancer skills). Note,
|
||||
// this only works if the item is not low quality, set or unique. Note,
|
||||
// that this uses the vanilla min/max skill IDs for each class as the range for the skill pool,
|
||||
// so if you add new class skills to the end of the file, you should use automagic.txt instead
|
||||
StaffMods d2enum.Hero
|
||||
|
||||
// CostFormula
|
||||
// Does the game generate the sell/repair/buy prices of this iType based on its modifiers or does
|
||||
// it use only the cost specific in the respective item txt files. 2=Organ (
|
||||
// probably higher price based on unit that dropped the organ), 1=Yes, 0=No.
|
||||
// Note: Only applies to items that are not unique or set, for those the price is solely controlled
|
||||
// by the base item file and by the bonus to price given in SetItems and UniqueItems txt files.
|
||||
// The exact functionality remains unknown, as for example charms, have this disabled.
|
||||
CostFormula int
|
||||
|
||||
// Class
|
||||
// Contains the class code for the class that should be able to use this iType (
|
||||
// for class specific items).
|
||||
Class d2enum.Hero
|
||||
|
||||
// VarInvGfx
|
||||
// This column contains the sum of randomly picked inventory graphics this iType can have.
|
||||
VarInvGfx int
|
||||
|
||||
// InvGfx1-6
|
||||
// This column contains the file names of the inventory graphics that are randomly picked for
|
||||
// this iType, so if you use columns 1-3, you will set VarInvGfx to 3 (duh).
|
||||
InvGfx1 string
|
||||
InvGfx2 string
|
||||
InvGfx3 string
|
||||
InvGfx4 string
|
||||
InvGfx5 string
|
||||
InvGfx6 string
|
||||
|
||||
// StorePage
|
||||
// The page code for the page a vendor should place this iType in when sold,
|
||||
// if you enable the magic tab in D2Client.dll,
|
||||
// you need to use the proper code here to put items in that tab.
|
||||
// Right now the ones used are weap = weapons1 and 2, armo = armor and misc = miscellaneous.
|
||||
StorePage string
|
||||
}
|
||||
|
||||
// ItemTypes stores all of the ItemTypeRecords
|
||||
var ItemTypes map[string]*ItemTypeRecord //nolint:gochecknoglobals // Currently global by design, only written once
|
||||
|
||||
// LoadItemTypes loads ItemType records
|
||||
func LoadItemTypes(file []byte) {
|
||||
ItemTypes = make(map[string]*ItemTypeRecord)
|
||||
|
||||
charCodeMap := map[string]d2enum.Hero{
|
||||
"ama": d2enum.HeroAmazon,
|
||||
"ass": d2enum.HeroAssassin,
|
||||
"bar": d2enum.HeroBarbarian,
|
||||
"dru": d2enum.HeroDruid,
|
||||
"nec": d2enum.HeroNecromancer,
|
||||
"pal": d2enum.HeroPaladin,
|
||||
"sor": d2enum.HeroSorceress,
|
||||
}
|
||||
|
||||
d := d2common.LoadDataDictionary(file)
|
||||
for d.Next() {
|
||||
if d.String("*eol") == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
itemType := &ItemTypeRecord{
|
||||
Name: d.String("ItemType"),
|
||||
Code: d.String("Code"),
|
||||
Equiv1: d.String("Equiv1"),
|
||||
Equiv2: d.String("Equiv2"),
|
||||
Repair: d.Number("Repair") > 0,
|
||||
Body: d.Number("Body") > 0,
|
||||
BodyLoc1: d.Number("BodyLoc1"),
|
||||
BodyLoc2: d.Number("BodyLoc2"),
|
||||
Shoots: d.String("Shoots"),
|
||||
Quiver: d.String("Quiver"),
|
||||
Throwable: d.Number("Throwable") > 0,
|
||||
Reload: d.Number("Reload") > 0,
|
||||
ReEquip: d.Number("ReEquip") > 0,
|
||||
AutoStack: d.Number("AutoStack") > 0,
|
||||
Magic: d.Number("Magic") > 0,
|
||||
Rare: d.Number("Rare") > 0,
|
||||
Normal: d.Number("Normal") > 0,
|
||||
Charm: d.Number("Charm") > 0,
|
||||
Gem: d.Number("Gem") > 0,
|
||||
Beltable: d.Number("Beltable") > 0,
|
||||
MaxSock1: d.Number("MaxSock1"),
|
||||
MaxSock25: d.Number("MaxSock25"),
|
||||
MaxSock40: d.Number("MaxSock40"),
|
||||
TreasureClass: d.Number("TreasureClass"),
|
||||
Rarity: d.Number("Rarity"),
|
||||
StaffMods: charCodeMap[d.String("StaffMods")],
|
||||
CostFormula: d.Number("CostFormula"),
|
||||
Class: charCodeMap[d.String("Class")],
|
||||
VarInvGfx: d.Number("VarInvGfx"),
|
||||
InvGfx1: d.String("InvGfx1"),
|
||||
InvGfx2: d.String("InvGfx2"),
|
||||
InvGfx3: d.String("InvGfx3"),
|
||||
InvGfx4: d.String("InvGfx4"),
|
||||
InvGfx5: d.String("InvGfx5"),
|
||||
InvGfx6: d.String("InvGfx6"),
|
||||
StorePage: d.String("StorePage"),
|
||||
}
|
||||
|
||||
ItemTypes[itemType.Name] = itemType
|
||||
}
|
||||
|
||||
if d.Err != nil {
|
||||
panic(d.Err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d ItemType records", len(ItemTypes))
|
||||
}
|
275
d2common/d2data/d2datadict/set_items.go
Normal file
275
d2common/d2data/d2datadict/set_items.go
Normal file
@ -0,0 +1,275 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"log"
|
||||
)
|
||||
|
||||
// SetItemRecord represents a set item
|
||||
type SetItemRecord struct {
|
||||
// StringTableKey (index)
|
||||
// string key to item's name in a .tbl file
|
||||
StringTableKey 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
|
||||
|
||||
// Prop (prop1 to prop9)
|
||||
// An ID pointer of a property from Properties.txt,
|
||||
// these columns control each of the nine different fixed (
|
||||
// blue) modifiers a set item can grant you at most.
|
||||
Prop [9]string
|
||||
|
||||
// Par (par1 to par9)
|
||||
// The parameter passed on to the associated property, this is used to pass skill IDs, state IDs,
|
||||
// monster IDs, montype IDs and the like on to the properties that require them,
|
||||
// these fields support calculations.
|
||||
Par [9]int
|
||||
|
||||
// Min, Max (min1 to min9, max1 to max9)
|
||||
// Minimum value to assign to the associated (blue) property.
|
||||
// Certain properties have special interpretations based on stat encoding (e.g.
|
||||
// chance-to-cast and charged skills). See the File Guide for Properties.txt and ItemStatCost.
|
||||
// txt for further details.
|
||||
Min [9]int
|
||||
Max [9]int
|
||||
|
||||
// APropA, APropB (aprop1a,aprop1b to aprop5a,aprop5b)
|
||||
// An ID pointer of a property from Properties.txt,
|
||||
// these columns control each of the five pairs of different variable (
|
||||
// green) modifiers a set item can grant you at most.
|
||||
APropA [5]string
|
||||
APropB [5]string
|
||||
|
||||
// AParA, AParB (apar1a,apar1b to apar5a,apar5b)
|
||||
// The parameter passed on to the associated property, this is used to pass skill IDs, state IDs,
|
||||
// monster IDs, montype IDs and the like on to the properties that require them,
|
||||
// these fields support calculations.
|
||||
AParA [5]int
|
||||
AParB [5]int
|
||||
|
||||
// AMinA, AMinB, AMaxA, AMaxB (amin1a,amin1b to amin5a,amin5b)
|
||||
// Minimum value to assign to the associated property.
|
||||
// Certain properties have special interpretations based on stat encoding (e.g.
|
||||
// chance-to-cast and charged skills). See the File Guide for Properties.txt and ItemStatCost.
|
||||
// txt for further details.
|
||||
AMinA [5]int
|
||||
AMinB [5]int
|
||||
AMaxA [5]int
|
||||
AMaxB [5]int
|
||||
}
|
||||
|
||||
// SetItems holds all of the SetItemRecords
|
||||
var SetItems []*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([]*SetItemRecord, 0)
|
||||
|
||||
d := d2common.LoadDataDictionary(file)
|
||||
|
||||
for d.Next() {
|
||||
record := &SetItemRecord{
|
||||
StringTableKey: 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"),
|
||||
Prop: [9]string{
|
||||
d.String("prop1"),
|
||||
d.String("prop2"),
|
||||
d.String("prop3"),
|
||||
d.String("prop4"),
|
||||
d.String("prop5"),
|
||||
d.String("prop6"),
|
||||
d.String("prop7"),
|
||||
d.String("prop8"),
|
||||
d.String("prop9"),
|
||||
},
|
||||
Par: [9]int{
|
||||
d.Number("par1"),
|
||||
d.Number("par2"),
|
||||
d.Number("par3"),
|
||||
d.Number("par4"),
|
||||
d.Number("par5"),
|
||||
d.Number("par6"),
|
||||
d.Number("par7"),
|
||||
d.Number("par8"),
|
||||
d.Number("par9"),
|
||||
},
|
||||
Min: [9]int{
|
||||
d.Number("min1"),
|
||||
d.Number("min2"),
|
||||
d.Number("min3"),
|
||||
d.Number("min4"),
|
||||
d.Number("min5"),
|
||||
d.Number("min6"),
|
||||
d.Number("min7"),
|
||||
d.Number("min8"),
|
||||
d.Number("min9"),
|
||||
},
|
||||
Max: [9]int{
|
||||
d.Number("max1"),
|
||||
d.Number("max2"),
|
||||
d.Number("max3"),
|
||||
d.Number("max4"),
|
||||
d.Number("max5"),
|
||||
d.Number("max6"),
|
||||
d.Number("max7"),
|
||||
d.Number("max8"),
|
||||
d.Number("max9"),
|
||||
},
|
||||
APropA: [5]string{
|
||||
d.String("aprop1a"),
|
||||
d.String("aprop2a"),
|
||||
d.String("aprop3a"),
|
||||
d.String("aprop4a"),
|
||||
d.String("aprop5a"),
|
||||
},
|
||||
APropB: [5]string{
|
||||
d.String("aprop1b"),
|
||||
d.String("aprop2b"),
|
||||
d.String("aprop3b"),
|
||||
d.String("aprop4b"),
|
||||
d.String("aprop5b"),
|
||||
},
|
||||
AParA: [5]int{
|
||||
d.Number("apar1a"),
|
||||
d.Number("apar2a"),
|
||||
d.Number("apar3a"),
|
||||
d.Number("apar4a"),
|
||||
d.Number("apar5a"),
|
||||
},
|
||||
AParB: [5]int{
|
||||
d.Number("apar1b"),
|
||||
d.Number("apar2b"),
|
||||
d.Number("apar3b"),
|
||||
d.Number("apar4b"),
|
||||
d.Number("apar5b"),
|
||||
},
|
||||
AMinA: [5]int{
|
||||
d.Number("amin1a"),
|
||||
d.Number("amin2a"),
|
||||
d.Number("amin3a"),
|
||||
d.Number("amin4a"),
|
||||
d.Number("amin5a"),
|
||||
},
|
||||
AMinB: [5]int{
|
||||
d.Number("amin1b"),
|
||||
d.Number("amin2b"),
|
||||
d.Number("amin3b"),
|
||||
d.Number("amin4b"),
|
||||
d.Number("amin5b"),
|
||||
},
|
||||
AMaxA: [5]int{
|
||||
d.Number("amax1a"),
|
||||
d.Number("amax2a"),
|
||||
d.Number("amax3a"),
|
||||
d.Number("amax4a"),
|
||||
d.Number("amax5a"),
|
||||
},
|
||||
AMaxB: [5]int{
|
||||
d.Number("amax1b"),
|
||||
d.Number("amax2b"),
|
||||
d.Number("amax3b"),
|
||||
d.Number("amax4b"),
|
||||
d.Number("amax5b"),
|
||||
},
|
||||
}
|
||||
|
||||
SetItems = append(SetItems, record)
|
||||
}
|
||||
|
||||
if d.Err != nil {
|
||||
panic(d.Err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d SetItem records", len(SetItems))
|
||||
}
|
190
d2common/d2data/d2datadict/sets.go
Normal file
190
d2common/d2data/d2datadict/sets.go
Normal file
@ -0,0 +1,190 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
// PCodeA, PCodeB -- PCode2a,PCode2b to PCode5a,PCode5b
|
||||
// An ID pointer of a property from Properties.txt,
|
||||
// these columns control each of the five pairs of different partial set modifiers a set item can
|
||||
// grant you at most.
|
||||
PCodeA [4]string
|
||||
PCodeB [4]string
|
||||
|
||||
// PParamA, PParamB -- PParam2[a|b] to PParam5[a|b]
|
||||
// The parameter passed on to the associated property, this is used to pass skill IDs, state IDs,
|
||||
// monster IDs, montype IDs and the like on to the properties that require them,
|
||||
// these fields support calculations.
|
||||
PParamA [4]int
|
||||
PParamB [4]int
|
||||
|
||||
// PMinA, PMaxA, PMinB, PMaxB -- P[Min|Max]2[a|b] to P[Min|Max]5[a|b]
|
||||
// Minimum value to assign to the associated property.
|
||||
// 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.
|
||||
PMinA [4]int
|
||||
PMaxA [4]int
|
||||
PMinB [4]int
|
||||
PMaxB [4]int
|
||||
|
||||
// FCode -- FCode1 to FCode8
|
||||
// An ID pointer of a property from Properties.txt,
|
||||
// these columns control each of the eight different full set modifiers a set item can grant you
|
||||
// at most.
|
||||
FCode [8]string
|
||||
|
||||
// FParam -- FParam1 to FParam8
|
||||
// The parameter passed on to the associated property, this is used to pass skill IDs, state IDs,
|
||||
// monster IDs, montype IDs and the like on to the properties that require them,
|
||||
// these fields support calculations.
|
||||
FParam [8]int
|
||||
|
||||
// FMin -- FMin1 to FMin8
|
||||
// Minimum value to assign to the associated property.
|
||||
// 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.
|
||||
FMin [8]int
|
||||
|
||||
// FMax -- FMax1 to FMax8
|
||||
// Maximum value to assign to the associated property.
|
||||
// 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.
|
||||
FMax [8]int
|
||||
}
|
||||
|
||||
// SetRecords contain the set records from sets.txt
|
||||
var SetRecords map[string]*SetRecord
|
||||
|
||||
// LoadSetRecords loads set records from sets.txt
|
||||
func LoadSets(file []byte) {
|
||||
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"),
|
||||
PCodeA: [4]string{
|
||||
d.String("PCode2a"),
|
||||
d.String("PCode3a"),
|
||||
d.String("PCode4a"),
|
||||
d.String("PCode5a"),
|
||||
},
|
||||
PCodeB: [4]string{
|
||||
d.String("PCode2b"),
|
||||
d.String("PCode3b"),
|
||||
d.String("PCode4b"),
|
||||
d.String("PCode5b"),
|
||||
},
|
||||
PParamA: [4]int{
|
||||
d.Number("PParam2a"),
|
||||
d.Number("PParam3a"),
|
||||
d.Number("PParam4a"),
|
||||
d.Number("PParam5a"),
|
||||
},
|
||||
PParamB: [4]int{
|
||||
d.Number("PParam2b"),
|
||||
d.Number("PParam3b"),
|
||||
d.Number("PParam4b"),
|
||||
d.Number("PParam5b"),
|
||||
},
|
||||
PMinA: [4]int{
|
||||
d.Number("PMin2a"),
|
||||
d.Number("PMin3a"),
|
||||
d.Number("PMin4a"),
|
||||
d.Number("PMin5a"),
|
||||
},
|
||||
PMinB: [4]int{
|
||||
d.Number("PMin2b"),
|
||||
d.Number("PMin3b"),
|
||||
d.Number("PMin4b"),
|
||||
d.Number("PMin5b"),
|
||||
},
|
||||
PMaxA: [4]int{
|
||||
d.Number("PMax2a"),
|
||||
d.Number("PMax3a"),
|
||||
d.Number("PMax4a"),
|
||||
d.Number("PMax5a"),
|
||||
},
|
||||
PMaxB: [4]int{
|
||||
d.Number("PMax2b"),
|
||||
d.Number("PMax3b"),
|
||||
d.Number("PMax4b"),
|
||||
d.Number("PMax5b"),
|
||||
},
|
||||
FCode: [8]string{
|
||||
d.String("FCode1"),
|
||||
d.String("FCode2"),
|
||||
d.String("FCode3"),
|
||||
d.String("FCode4"),
|
||||
d.String("FCode5"),
|
||||
d.String("FCode6"),
|
||||
d.String("FCode7"),
|
||||
d.String("FCode9"),
|
||||
},
|
||||
FParam: [8]int{
|
||||
d.Number("FParam1"),
|
||||
d.Number("FParam2"),
|
||||
d.Number("FParam3"),
|
||||
d.Number("FParam4"),
|
||||
d.Number("FParam5"),
|
||||
d.Number("FParam6"),
|
||||
d.Number("FParam7"),
|
||||
d.Number("FParam9"),
|
||||
},
|
||||
FMin: [8]int{
|
||||
d.Number("FMin1"),
|
||||
d.Number("FMin2"),
|
||||
d.Number("FMin3"),
|
||||
d.Number("FMin4"),
|
||||
d.Number("FMin5"),
|
||||
d.Number("FMin6"),
|
||||
d.Number("FMin7"),
|
||||
d.Number("FMin9"),
|
||||
},
|
||||
FMax: [8]int{
|
||||
d.Number("FMax1"),
|
||||
d.Number("FMax2"),
|
||||
d.Number("FMax3"),
|
||||
d.Number("FMax4"),
|
||||
d.Number("FMax5"),
|
||||
d.Number("FMax6"),
|
||||
d.Number("FMax7"),
|
||||
d.Number("FMax9"),
|
||||
},
|
||||
}
|
||||
|
||||
SetRecords[record.Key] = record
|
||||
}
|
||||
|
||||
if d.Err != nil {
|
||||
panic(d.Err)
|
||||
}
|
||||
|
||||
log.Printf("Loaded %d Sets records", len(SetRecords))
|
||||
}
|
@ -180,6 +180,11 @@ const (
|
||||
ObjectDetails = "/data/global/excel/Objects.txt"
|
||||
SoundSettings = "/data/global/excel/Sounds.txt"
|
||||
ItemStatCost = "/data/global/excel/ItemStatCost.txt"
|
||||
ItemTypes = "/data/global/excel/ItemTypes.txt"
|
||||
Sets = "/data/global/excel/Sets.txt"
|
||||
SetItems = "/data/global/excel/SetItems.txt"
|
||||
AutoMagic = "/data/global/excel/automagic.txt"
|
||||
BodyLocations = "/data/global/excel/bodylocs.txt"
|
||||
Properties = "/data/global/excel/Properties.txt"
|
||||
Hireling = "/data/global/excel/hireling.txt"
|
||||
DifficultyLevels = "/data/global/excel/difficultylevels.txt"
|
||||
|
Loading…
Reference in New Issue
Block a user