mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-05 08:07:51 -05:00
DataDictionary loader for ItemStatCost (#333)
* adding rules for swap files to .gitignore * main, d2common: load Magic/Rare/Unique Affix * d2common: item affixes only removed Rare/Unique Prefix/Suffix as those are related to monsters, not items. * removed debug print from item_affix.go * changed item affix type names for clarity, removed debug print from data_dictionary * d2common: item affix datadict and records Item Affixes are defined in `/data/global/excel/Magic{Prefix,Suffix}.txt` Rare and Unique Pre/Suffixes seem to be for monsters, not items. d2common: item affixes only removed Rare/Unique Prefix/Suffix as those are related to monsters, not items. removed debug print from item_affix.go changed item affix type names for clarity, removed debug print from data_dictionary * reverting to pre-allocating memory for parsing txt lines * removing the rest of the rare/unique definitions * removing the rest of the rare/unique definitions * adding ItemStatCost data dict loader
This commit is contained in:
parent
80877380af
commit
a25e42518d
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,4 +8,6 @@
|
||||
/OpenDiablo2.exe
|
||||
/OpenDiablo2
|
||||
**/*.pprof
|
||||
*.swp
|
||||
.*.swp
|
||||
tags
|
320
d2common/d2data/d2datadict/itemstatcost.go
Normal file
320
d2common/d2data/d2datadict/itemstatcost.go
Normal file
@ -0,0 +1,320 @@
|
||||
package d2datadict
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"log"
|
||||
)
|
||||
|
||||
// refer to https://d2mods.info/forum/kb/viewarticle?a=448
|
||||
type ItemStatCostRecord struct {
|
||||
Name string
|
||||
Index int
|
||||
|
||||
Signed bool // whether the stat is signed
|
||||
KeepZero bool // prevent from going negative (assume only client side)
|
||||
|
||||
// path_d2.mpq version doesnt have Ranged columne, excluding for now
|
||||
// Ranged bool // game attempts to keep stat in a range, like strength >-1
|
||||
MinAccr int // minimum ranged value
|
||||
|
||||
UpdateAnimRate bool // when altered, forces speed handler to adjust speed
|
||||
|
||||
SendOther bool // whether to send to other clients
|
||||
SendBits int // #bits to send in stat update
|
||||
SendParam int // #bits to send in stat update
|
||||
|
||||
Saved bool // whether this stat is saved in .d2s files
|
||||
SavedSigned bool // whether the stat is saved as signed/unsigned
|
||||
SavedBits int // #bits allocated to the value in .d2s file
|
||||
|
||||
SaveBits int // #bits saved to .d2s files, max == 2^SaveBits-1
|
||||
SaveAdd int // how large the negative range is (lowers max, as well)
|
||||
SaveParamBits int // #param bits are saved (safe value is 17)
|
||||
|
||||
Encode EncodingType // how the stat is encoded in .d2s files
|
||||
|
||||
CallbackEnabled bool // whether callback fn is called if value changes
|
||||
|
||||
// these two fields control additional cost on items
|
||||
// cost * (1 + value * multiply / 1024)) + add (...)
|
||||
CostAdd int
|
||||
CostMultiply int
|
||||
// CostDivide // exists in txt, but division hardcoded to 1024
|
||||
// if divide is used, could we do (?):
|
||||
// cost * (1 + value * multiply / divide)) + add (...)
|
||||
|
||||
ValShift int // controls how stat is stored in .d2s
|
||||
// so that you can save `+1` instead of `+256`
|
||||
|
||||
OperatorType OperatorType
|
||||
OpParam int
|
||||
OpBase string
|
||||
OpStat1 string
|
||||
OpStat2 string
|
||||
OpStat3 string
|
||||
|
||||
Direct bool // whether is temporary or permanent
|
||||
MaxStat string // if Direct true, will not exceed val of MaxStat
|
||||
|
||||
ItemSpecific bool // prevents stacking with an existing stat on item
|
||||
// like when socketing a jewel
|
||||
|
||||
DamageRelated bool // prevents stacking of stats while dual wielding
|
||||
|
||||
EventID1 d2enum.ItemEventType
|
||||
EventID2 d2enum.ItemEventType
|
||||
EventFuncID1 d2enum.ItemEventFuncID
|
||||
EventFuncID2 d2enum.ItemEventFuncID
|
||||
|
||||
DescPriority int // determines order when displayed
|
||||
DescFnID d2enum.DescFuncID
|
||||
DescFn interface{} // the sprintf func
|
||||
|
||||
// Controls whenever and if so in what way the stat value is shown
|
||||
// 0 = doesn't show the value of the stat
|
||||
// 1 = shows the value of the stat infront of the description
|
||||
// 2 = shows the value of the stat after the description.
|
||||
DescVal int
|
||||
DescStrPos string // string used when val is positive
|
||||
DescStrNeg string
|
||||
DescStr2 string // additional string used by some string funcs
|
||||
|
||||
// when stats in the same group have the same value they use the
|
||||
// group func for desc (they need to be in the same affix)
|
||||
DescGroup int
|
||||
DescGroupFuncID d2enum.DescFuncID
|
||||
DescGroupFn interface{} // group sprintf func
|
||||
DescGroupVal int
|
||||
DescGroupStrPos string // string used when val is positive
|
||||
DescGroupStrNeg string
|
||||
DescGroupStr2 string // additional string used by some string funcs
|
||||
|
||||
// Stay far away from this column unless you really know what you're
|
||||
// doing and / or work for Blizzard, this column is used during bin-file
|
||||
// creation to generate a cache regulating the op-stat stuff and other
|
||||
// things, changing it can be futile, it works like the constants column
|
||||
// in MonUMod.txt and has no other relation to ItemStatCost.txt, the first
|
||||
// stat in the file simply must have this set or else you may break the
|
||||
// entire op stuff.
|
||||
Stuff string // ? TODO ?
|
||||
}
|
||||
|
||||
type EncodingType int
|
||||
|
||||
const (
|
||||
// TODO: determine other encoding types.
|
||||
// didn't see anything about how this stuff is encoded, or the types...
|
||||
EncodeDefault = EncodingType(iota)
|
||||
)
|
||||
|
||||
type OperatorType int // for dynamic properties
|
||||
|
||||
const (
|
||||
// just adds the stat to the unit directly
|
||||
OpDefault = OperatorType(iota)
|
||||
|
||||
// adds opstat.base * statvalue / 100 to the opstat.
|
||||
Op1
|
||||
|
||||
// adds (statvalue * basevalue) / (2 ^ param) to the opstat
|
||||
// this does not work properly with any stat other then level because of the
|
||||
// way this is updated, it is only refreshed when you re-equip the item,
|
||||
// your character is saved or you level up, similar to passive skills, just
|
||||
// because it looks like it works in the item description
|
||||
// does not mean it does, the game just recalculates the information in the
|
||||
// description every frame, while the values remain unchanged serverside.
|
||||
Op2
|
||||
|
||||
// this is a percentage based version of op #2
|
||||
// look at op #2 for information about the formula behind it, just
|
||||
// remember the stat is increased by a percentage rather then by adding
|
||||
// an integer.
|
||||
Op3
|
||||
|
||||
// this works the same way op #2 works, however the stat bonus is
|
||||
// added to the item and not to the player (so that +defense per level
|
||||
// properly adds the defense to the armor and not to the character
|
||||
// directly!)
|
||||
Op4
|
||||
|
||||
// this works like op #4 but is percentage based, it is used for percentage
|
||||
// based increase of stats that are found on the item itself, and not stats
|
||||
// that are found on the character.
|
||||
Op5
|
||||
|
||||
// like for op #7, however this adds a plain bonus to the stat, and just
|
||||
// like #7 it also doesn't work so I won't bother to explain the arithmetic
|
||||
// behind it either.
|
||||
Op6
|
||||
|
||||
// this is used to increase a stat based on the current daytime of the game
|
||||
// world by a percentage, there is no need to explain the arithmetics
|
||||
// behind it because frankly enough it just doesn't work serverside, it
|
||||
// only updates clientside so this op is essentially useless.
|
||||
Op7
|
||||
|
||||
// hardcoded to work only with maxmana, this will apply the proper amount
|
||||
// of mana to your character based on CharStats.txt for the amount of energy
|
||||
// the stat added (doesn't work for non characters)
|
||||
Op8
|
||||
|
||||
// hardcoded to work only with maxhp and maxstamina, this will apply the
|
||||
// proper amount of maxhp and maxstamina to your character based on
|
||||
// CharStats.txt for the amount of vitality the stat added (doesn't work
|
||||
// for non characters)
|
||||
Op9
|
||||
|
||||
// doesn't do anything, this has no switch case in the op function.
|
||||
Op10
|
||||
|
||||
// adds opstat.base * statvalue / 100 similar to 1 and 13, the code just
|
||||
// does a few more checks
|
||||
Op11
|
||||
|
||||
// doesn't do anything, this has no switch case in the op function.
|
||||
Op12
|
||||
|
||||
// adds opstat.base * statvalue / 100 to the value of opstat, this is
|
||||
// useable only on items it will not apply the bonus to other unit types
|
||||
// (this is why it is used for +% durability, +% level requirement,
|
||||
// +% damage, +% defense ).
|
||||
Op13
|
||||
)
|
||||
|
||||
/* column names from path_d2.mpq/data/global/excel/ItemStatCost.txt
|
||||
Stat
|
||||
ID
|
||||
Send Other
|
||||
Signed
|
||||
Send Bits
|
||||
Send Param Bits
|
||||
UpdateAnimRate
|
||||
Saved
|
||||
CSvSigned
|
||||
CSvBits
|
||||
CSvParam
|
||||
fCallback
|
||||
fMin
|
||||
MinAccr
|
||||
Encode
|
||||
Add
|
||||
Multiply
|
||||
Divide
|
||||
ValShift
|
||||
1.09-Save Bits
|
||||
1.09-Save Add
|
||||
Save Bits
|
||||
Save Add
|
||||
Save Param Bits
|
||||
keepzero
|
||||
op
|
||||
op param
|
||||
op base
|
||||
op stat1
|
||||
op stat2
|
||||
op stat3
|
||||
direct
|
||||
maxstat
|
||||
itemspecific
|
||||
damagerelated
|
||||
itemevent1
|
||||
itemeventfunc1
|
||||
itemevent2
|
||||
itemeventfunc2
|
||||
descpriority
|
||||
descfunc
|
||||
descval
|
||||
descstrpos
|
||||
descstrneg
|
||||
descstr2
|
||||
dgrp
|
||||
dgrpfunc
|
||||
dgrpval
|
||||
dgrpstrpos
|
||||
dgrpstrneg
|
||||
dgrpstr2
|
||||
stuff
|
||||
*eol
|
||||
*/
|
||||
|
||||
var ItemStatCosts map[string]*ItemStatCostRecord
|
||||
|
||||
func LoadItemStatCosts(file []byte) {
|
||||
ItemStatCosts = make(map[string]*ItemStatCostRecord, 0)
|
||||
d := d2common.LoadDataDictionary(string(file))
|
||||
r := make([]*ItemStatCostRecord, 0)
|
||||
|
||||
for idx, _ := range d.Data {
|
||||
record := &ItemStatCostRecord{
|
||||
Name: d.GetString("Stat", idx),
|
||||
Index: d.GetNumber("ID", idx),
|
||||
|
||||
Signed: d.GetNumber("Signed", idx) > 0,
|
||||
KeepZero: d.GetNumber("keepzero", idx) > 0,
|
||||
|
||||
// Ranged: d.GetNumber("Ranged", idx) > 0,
|
||||
MinAccr: d.GetNumber("MinAccr", idx),
|
||||
|
||||
UpdateAnimRate: d.GetNumber("UpdateAnimRate", idx) > 0,
|
||||
|
||||
SendOther: d.GetNumber("Send Other", idx) > 0,
|
||||
SendBits: d.GetNumber("Send Bits", idx),
|
||||
SendParam: d.GetNumber("Send Param Bits", idx),
|
||||
|
||||
Saved: d.GetNumber("CSvBits", idx) > 0,
|
||||
SavedSigned: d.GetNumber("CSvSigned", idx) > 0,
|
||||
SavedBits: d.GetNumber("CSvBits", idx),
|
||||
SaveBits: d.GetNumber("Save Bits", idx),
|
||||
SaveAdd: d.GetNumber("Save Add", idx),
|
||||
SaveParamBits: d.GetNumber("Save Param Bits", idx),
|
||||
|
||||
Encode: EncodingType(d.GetNumber("Encode", idx)),
|
||||
|
||||
CallbackEnabled: d.GetNumber("fCallback", idx) > 0,
|
||||
|
||||
CostAdd: d.GetNumber("Add", idx),
|
||||
CostMultiply: d.GetNumber("Multiply", idx),
|
||||
ValShift: d.GetNumber("ValShift", idx),
|
||||
|
||||
OperatorType: OperatorType(d.GetNumber("op", idx)),
|
||||
OpParam: d.GetNumber("op param", idx),
|
||||
OpBase: d.GetString("op base", idx),
|
||||
OpStat1: d.GetString("op stat1", idx),
|
||||
OpStat2: d.GetString("op stat2", idx),
|
||||
OpStat3: d.GetString("op stat3", idx),
|
||||
|
||||
Direct: d.GetNumber("direct", idx) > 0,
|
||||
MaxStat: d.GetString("maxstat", idx),
|
||||
|
||||
ItemSpecific: d.GetNumber("itemspecific", idx) > 0,
|
||||
DamageRelated: d.GetNumber("damagerelated", idx) > 0,
|
||||
|
||||
EventID1: d2enum.GetItemEventType(d.GetString("itemevent1", idx)),
|
||||
EventID2: d2enum.GetItemEventType(d.GetString("itemevent2", idx)),
|
||||
EventFuncID1: d2enum.GetItemEventFuncID(d.GetNumber("itemeventfunc1", idx)),
|
||||
EventFuncID2: d2enum.GetItemEventFuncID(d.GetNumber("itemeventfunc2", idx)),
|
||||
|
||||
DescPriority: d.GetNumber("descpriority", idx),
|
||||
DescFnID: d2enum.DescFuncID(d.GetNumber("descfunc", idx)),
|
||||
DescFn: d2enum.GetDescFunction(d2enum.DescFuncID(d.GetNumber("descfunc", idx))),
|
||||
DescVal: d.GetNumber("descval", idx),
|
||||
DescStrPos: d.GetString("descstrpos", idx),
|
||||
DescStrNeg: d.GetString("descstrneg", idx),
|
||||
DescStr2: d.GetString("descstr2", idx),
|
||||
|
||||
DescGroup: d.GetNumber("dgrp", idx),
|
||||
DescGroupFuncID: d2enum.DescFuncID(d.GetNumber("dgrpfunc", idx)),
|
||||
DescGroupFn: d2enum.GetDescFunction(d2enum.DescFuncID(d.GetNumber("dgrpfunc", idx))),
|
||||
DescGroupVal: d.GetNumber("dgrpval", idx),
|
||||
DescGroupStrPos: d.GetString("dgrpstrpos", idx),
|
||||
DescGroupStrNeg: d.GetString("dgrpstrneg", idx),
|
||||
DescGroupStr2: d.GetString("dgrpstr2", idx),
|
||||
|
||||
Stuff: d.GetString("stuff", idx),
|
||||
}
|
||||
|
||||
r = append(r, record)
|
||||
}
|
||||
log.Printf("Loaded %d ItemStatCost records", len(r))
|
||||
}
|
194
d2common/d2enum/description_functions.go
Normal file
194
d2common/d2enum/description_functions.go
Normal file
@ -0,0 +1,194 @@
|
||||
package d2enum
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type DescFuncID int
|
||||
|
||||
func Format1(value float64, string1 string) string {
|
||||
// +[value] [string1]
|
||||
return fmt.Sprintf("+%f %s", value, string1)
|
||||
}
|
||||
|
||||
func Format2(value float64, string1 string) string {
|
||||
// [value]% [string1]
|
||||
return fmt.Sprintf("%f%% %s", value, string1)
|
||||
}
|
||||
|
||||
func Format3(value float64, string1 string) string {
|
||||
// [value] [string1]
|
||||
return fmt.Sprintf("%f %s", value, string1)
|
||||
}
|
||||
|
||||
func Format4(value float64, string1 string) string {
|
||||
// +[value]% [string1]
|
||||
return fmt.Sprintf("+%f%% %s", value, string1)
|
||||
}
|
||||
|
||||
func Format5(value float64, string1 string) string {
|
||||
// [value*100/128]% [string1]
|
||||
return fmt.Sprintf("%f%% %s", (value*100.0)/128.0, string1)
|
||||
}
|
||||
|
||||
func Format6(value float64, string1, string2 string) string {
|
||||
// +[value] [string1] [string2]
|
||||
return fmt.Sprintf("+%f %s %s", value, string1, string2)
|
||||
}
|
||||
|
||||
func Format7(value float64, string1, string2 string) string {
|
||||
// [value]% [string1] [string2]
|
||||
return fmt.Sprintf("%f%% %s %s", value, string1, string2)
|
||||
}
|
||||
|
||||
func Format8(value float64, string1, string2 string) string {
|
||||
// +[value]% [string1] [string2]
|
||||
return fmt.Sprintf("+%f%% %s %s", value, string1, string2)
|
||||
}
|
||||
|
||||
func Format9(value float64, string1, string2 string) string {
|
||||
// [value] [string1] [string2]
|
||||
return fmt.Sprintf("%f %s %s", value, string1, string2)
|
||||
}
|
||||
|
||||
func Format10(value float64, string1, string2 string) string {
|
||||
// [value*100/128]% [string1] [string2]
|
||||
return fmt.Sprintf("%f%% %s %s", (value*100.0)/128.0, string1, string2)
|
||||
}
|
||||
|
||||
func Format11(value float64) string {
|
||||
// Repairs 1 Durability In [100 / value] Seconds
|
||||
return fmt.Sprintf("Repairs 1 Durability In %.0f Seconds", 100.0/value)
|
||||
}
|
||||
|
||||
func Format12(value float64, string1 string) string {
|
||||
// +[value] [string1]
|
||||
return fmt.Sprintf("+%f %s", value, string1)
|
||||
}
|
||||
|
||||
func Format13(value float64, class string) string {
|
||||
// +[value] to [class] Skill Levels
|
||||
return fmt.Sprintf("+%.0f to %s Skill Levels", value, class)
|
||||
}
|
||||
|
||||
func Format14(value float64, skilltab, class string) string {
|
||||
// +[value] to [skilltab] Skill Levels ([class] Only)
|
||||
fmtStr := "+%.0f to %s Skill Levels (%s Only)"
|
||||
return fmt.Sprintf(fmtStr, value, skilltab, class)
|
||||
}
|
||||
|
||||
func Format15(value float64, slvl int, skill, event string) string {
|
||||
// [value]% chance to cast [slvl] [skill] on [event]
|
||||
fmtStr := "%.0f%% chance to cast %d %s on %s"
|
||||
return fmt.Sprintf(fmtStr, value, slvl, skill, event)
|
||||
}
|
||||
|
||||
func Format16(slvl int, skill string) string {
|
||||
// Level [sLvl] [skill] Aura When Equipped
|
||||
return fmt.Sprintf("Level %d %s Aura When Equipped", slvl, skill)
|
||||
}
|
||||
|
||||
func Format17(value float64, string1 string, time int) string {
|
||||
// [value] [string1] (Increases near [time])
|
||||
return fmt.Sprintf("%f %s (Increases near %d)", value, string1, time)
|
||||
}
|
||||
|
||||
func Format18(value float64, string1 string, time int) string {
|
||||
// [value]% [string1] (Increases near [time])
|
||||
return fmt.Sprintf("%f%% %s (Increases near %d)", value, string1, time)
|
||||
}
|
||||
|
||||
func Format19(value float64, string1 string) string {
|
||||
// this is used by stats that use Blizzard's sprintf implementation
|
||||
// (if you don't know what that is, it won't be of interest to you
|
||||
// eitherway I guess), look at how prismatic is setup, the string is
|
||||
// the format that gets passed to their sprintf spinoff.
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
func Format20(value float64, string1 string) string {
|
||||
// [value * -1]% [string1]
|
||||
return fmt.Sprintf("%f%% %s", value*-1.0, string1)
|
||||
}
|
||||
|
||||
func Format21(value float64, string1 string) string {
|
||||
// [value * -1] [string1]
|
||||
return fmt.Sprintf("%f %s", value*-1.0, string1)
|
||||
}
|
||||
|
||||
func Format22(value float64, string1, montype string) string {
|
||||
// [value]% [string1] [montype]
|
||||
return fmt.Sprintf("%f%% %s %s", value, string1, montype)
|
||||
}
|
||||
|
||||
func Format23(value float64, string1 string) string {
|
||||
// (warning: this is bugged in vanilla and doesn't work properly
|
||||
// see CE forum)
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
func Format24(value float64, string1, monster string) string {
|
||||
// [value]% [string1] [monster]
|
||||
return fmt.Sprintf("%f%% %s %s", value, string1, monster)
|
||||
}
|
||||
|
||||
func Format25(slvl float64, skill string, charges, maxCharges int) string {
|
||||
// Level [slvl] [skill] ([charges]/[maxCharges] Charges)
|
||||
fmtStr := "Level %.0f %s (%d/%d Charges)"
|
||||
return fmt.Sprintf(fmtStr, slvl, skill, charges, maxCharges)
|
||||
}
|
||||
|
||||
func Format26(value float64, string1 string) string {
|
||||
// not used by vanilla, present in the code but I didn't test it yet
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
func Format27(value float64, string1 string) string {
|
||||
// not used by vanilla, present in the code but I didn't test it yet
|
||||
return "" // TODO
|
||||
}
|
||||
|
||||
func Format28(value float64, skill, class string) string {
|
||||
// +[value] to [skill] ([class] Only)
|
||||
return fmt.Sprintf("+%f to %s (%s Only)", value, skill, class)
|
||||
}
|
||||
|
||||
func Format29(value float64, skill string) string {
|
||||
// +[value] to [skill]
|
||||
return fmt.Sprintf("+%.0f to %s", value, skill)
|
||||
}
|
||||
|
||||
func GetDescFunction(n DescFuncID) interface{} {
|
||||
m := map[DescFuncID]interface{}{
|
||||
DescFuncID(0): Format1,
|
||||
DescFuncID(1): Format2,
|
||||
DescFuncID(2): Format3,
|
||||
DescFuncID(3): Format4,
|
||||
DescFuncID(4): Format5,
|
||||
DescFuncID(5): Format6,
|
||||
DescFuncID(6): Format7,
|
||||
DescFuncID(7): Format8,
|
||||
DescFuncID(8): Format9,
|
||||
DescFuncID(9): Format10,
|
||||
DescFuncID(10): Format11,
|
||||
DescFuncID(11): Format12,
|
||||
DescFuncID(12): Format13,
|
||||
DescFuncID(13): Format14,
|
||||
DescFuncID(14): Format15,
|
||||
DescFuncID(15): Format16,
|
||||
DescFuncID(16): Format17,
|
||||
DescFuncID(17): Format18,
|
||||
DescFuncID(18): Format19,
|
||||
DescFuncID(19): Format20,
|
||||
DescFuncID(20): Format21,
|
||||
DescFuncID(21): Format22,
|
||||
DescFuncID(22): Format23,
|
||||
DescFuncID(23): Format24,
|
||||
DescFuncID(24): Format25,
|
||||
DescFuncID(25): Format26,
|
||||
DescFuncID(26): Format27,
|
||||
DescFuncID(27): Format28,
|
||||
DescFuncID(28): Format29,
|
||||
}
|
||||
return m[n]
|
||||
}
|
143
d2common/d2enum/item_event_functions.go
Normal file
143
d2common/d2enum/item_event_functions.go
Normal file
@ -0,0 +1,143 @@
|
||||
package d2enum
|
||||
|
||||
type ItemEventFuncID int
|
||||
|
||||
const (
|
||||
// shoots a missile at the owner of a missile that has just hit you
|
||||
// (Chilling Armor uses this)
|
||||
ReflectMissile = ItemEventFuncID(iota)
|
||||
|
||||
// freezes the attacker for a set duration the attacker
|
||||
// (Frozen Armor uses this)
|
||||
FreezeAttacker
|
||||
|
||||
// does cold damage to and chills the attacker (Shiver Armor uses this)
|
||||
FreezeChillAttacker
|
||||
|
||||
// % of damage taken is done to the attacker
|
||||
// (Iron Maiden, thorns uses a hardcoded stat)
|
||||
ReflectPercentDamage
|
||||
|
||||
// % of damage done added to life, bypassing the targets resistance
|
||||
// (used by Life Tap)
|
||||
DamageDealtToHealth
|
||||
|
||||
// attacker takes physical damage of #
|
||||
AttackerTakesPhysical
|
||||
|
||||
// knocks the target back
|
||||
Knockback
|
||||
|
||||
// induces fear in the target making it run away
|
||||
InduceFear
|
||||
|
||||
// applies Dim Vision to the target (it casts the actual curse on the
|
||||
// monster)
|
||||
BlindTarget
|
||||
|
||||
// attacker takes lightning damage of #
|
||||
AttackerTakesLightning
|
||||
|
||||
// attacker takes fire damage of #
|
||||
AttackerTakesFire
|
||||
|
||||
// attacker takes cold damage of #
|
||||
AttackerTakesCold
|
||||
|
||||
// % damage taken is added to mana
|
||||
DamageTakenToMana
|
||||
|
||||
// freezes the target
|
||||
FreezeTarget
|
||||
|
||||
// causes the target to bleed and lose life (negative life regen)
|
||||
OpenWounds
|
||||
|
||||
// crushing blow against the target
|
||||
CrushingBlow
|
||||
|
||||
// mana after killing a monster
|
||||
ManaOnKillMonster
|
||||
|
||||
// life after killing a demon
|
||||
LifeOnKillDemon
|
||||
|
||||
// slows the target
|
||||
SlowTarget
|
||||
|
||||
// casts a skill against the defender
|
||||
CastSkillAgainstDefender
|
||||
|
||||
// casts a skill against the attacker
|
||||
CastSkillAgainstAttacker
|
||||
|
||||
// absorbs physical damage taken (used by Bone Armor)
|
||||
AbsorbPhysical
|
||||
|
||||
// transfers damage done from the summon to the owner (used by Blood Golem)
|
||||
TakeSummonDamage
|
||||
|
||||
// used by Energy Shield to absorb damage and shift it from life to mana
|
||||
ManaAbsorbsDamage
|
||||
|
||||
// absorbs elemental damage taken (used by Cyclone Armor)
|
||||
AbsorbElementalDamage
|
||||
|
||||
// transfers damage taken from the summon to the owner (used by Blood Golem)
|
||||
TakeSummonDamage2
|
||||
|
||||
// used to slow the attacker if he hits a unit that has the slow target stat
|
||||
// (used by Clay Golem)
|
||||
TargetSlowsTarget
|
||||
|
||||
// life after killing a monster
|
||||
LifeOnKillMonster
|
||||
|
||||
// destroys the corpse of a killed monster (rest in peace effect)
|
||||
RestInPeace
|
||||
|
||||
// cast a skill when the event occurs, without a target
|
||||
CastSkillWithoutTarget
|
||||
|
||||
// reanimate the target as the specified monster
|
||||
ReanimateTargetAsMonster
|
||||
)
|
||||
|
||||
func GetItemEventFuncID(n int) ItemEventFuncID {
|
||||
m := map[int]ItemEventFuncID{
|
||||
0: ReflectMissile,
|
||||
1: FreezeAttacker,
|
||||
2: FreezeChillAttacker,
|
||||
3: ReflectPercentDamage,
|
||||
4: DamageDealtToHealth,
|
||||
5: AttackerTakesPhysical,
|
||||
6: Knockback,
|
||||
7: InduceFear,
|
||||
8: BlindTarget,
|
||||
9: AttackerTakesLightning,
|
||||
10: AttackerTakesFire,
|
||||
11: AttackerTakesCold,
|
||||
12: DamageTakenToMana,
|
||||
13: FreezeTarget,
|
||||
14: OpenWounds,
|
||||
15: CrushingBlow,
|
||||
16: ManaOnKillMonster,
|
||||
17: LifeOnKillDemon,
|
||||
18: SlowTarget,
|
||||
19: CastSkillAgainstDefender,
|
||||
20: CastSkillAgainstAttacker,
|
||||
21: AbsorbPhysical,
|
||||
22: TakeSummonDamage,
|
||||
23: ManaAbsorbsDamage,
|
||||
24: AbsorbElementalDamage,
|
||||
25: TakeSummonDamage2,
|
||||
26: TargetSlowsTarget,
|
||||
27: LifeOnKillMonster,
|
||||
28: RestInPeace,
|
||||
29: CastSkillWithoutTarget,
|
||||
30: ReanimateTargetAsMonster,
|
||||
}
|
||||
return m[n]
|
||||
}
|
||||
|
||||
//? do i need to do this ? //go:generate stringer -linecomment -type AnimationMode
|
39
d2common/d2enum/item_events.go
Normal file
39
d2common/d2enum/item_events.go
Normal file
@ -0,0 +1,39 @@
|
||||
package d2enum
|
||||
|
||||
// used in ItemStatCost
|
||||
type ItemEventType int
|
||||
|
||||
const (
|
||||
HitByMissile = ItemEventType(iota) // hit By a Missile
|
||||
DamagedInMelee // Damaged in Melee
|
||||
DamagedByMissile // Damaged By Missile
|
||||
AttackedInMelee // melee Attack atttempt
|
||||
DoActive // do active state skill
|
||||
DoMeleeDamage // do damage in melee
|
||||
DoMissileDamage // do missile damage
|
||||
DoMeleeAttack // do melee attack
|
||||
DoMissileAttack // do missile attack
|
||||
Kill // killed something
|
||||
Killed // killed By something
|
||||
AbsorbDamage // dealt damage
|
||||
LevelUp // gain a level
|
||||
)
|
||||
|
||||
func GetItemEventType(s string) ItemEventType {
|
||||
strLookupTable := map[string]ItemEventType{
|
||||
"HitByMissile": HitByMissile,
|
||||
"DamagedInMelee": DamagedInMelee,
|
||||
"DamagedByMissile": DamagedByMissile,
|
||||
"AttackedInMelee": AttackedInMelee,
|
||||
"DoActive": DoActive,
|
||||
"DoMeleeDamage": DoMeleeDamage,
|
||||
"DoMissileDamage": DoMissileDamage,
|
||||
"DoMeleeAttack": DoMeleeAttack,
|
||||
"DoMissileAttack": DoMissileAttack,
|
||||
"Kill": Kill,
|
||||
"Killed": Killed,
|
||||
"AbsorbDamage": AbsorbDamage,
|
||||
"LevelUp": LevelUp,
|
||||
}
|
||||
return strLookupTable[s]
|
||||
}
|
@ -174,6 +174,7 @@ const (
|
||||
LevelDetails = "/data/global/excel/Levels.bin"
|
||||
ObjectDetails = "/data/global/excel/Objects.txt"
|
||||
SoundSettings = "/data/global/excel/Sounds.txt"
|
||||
ItemStatCost = "/data/global/excel/ItemStatCost.txt"
|
||||
|
||||
// --- Animations ---
|
||||
|
||||
|
2
main.go
2
main.go
@ -389,6 +389,8 @@ func loadDataDict() error {
|
||||
{d2resource.MonStats, d2datadict.LoadMonStats},
|
||||
{d2resource.MagicPrefix, d2datadict.LoadMagicPrefix},
|
||||
{d2resource.MagicSuffix, d2datadict.LoadMagicSuffix},
|
||||
{d2resource.ItemStatCost, d2datadict.LoadItemStatCosts},
|
||||
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
|
Loading…
Reference in New Issue
Block a user