diff --git a/d2app/app.go b/d2app/app.go index a09d1e31..34ab8fe3 100644 --- a/d2app/app.go +++ b/d2app/app.go @@ -259,6 +259,7 @@ func (a *App) loadDataDict() error { {d2resource.PlrMode, d2datadict.LoadPlrModes}, {d2resource.PetType, d2datadict.LoadPetTypes}, {d2resource.NPC, d2datadict.LoadNPCs}, + {d2resource.MonsterUniqueModifier, d2datadict.LoadMonsterUniqueModifiers}, } d2datadict.InitObjectRecords() diff --git a/d2common/d2data/d2datadict/monster_unique_modifiers.go b/d2common/d2data/d2datadict/monster_unique_modifiers.go new file mode 100644 index 00000000..ed18a079 --- /dev/null +++ b/d2common/d2data/d2datadict/monster_unique_modifiers.go @@ -0,0 +1,98 @@ +package d2datadict + +import ( + "log" + + "github.com/OpenDiablo2/OpenDiablo2/d2common" +) + +//MonsterUniqueModifierRecord represents a single line in monumod.txt +//Information gathered from [https://d2mods.info/forum/kb/viewarticle?a=161] +type MonsterUniqueModifierRecord struct { + //Name of modifer, not used by other files + Name string + + //ID of the modifier + //The Mod fields of SuperUniqueRecord refer to these ID's + ID int + + //If true, this modifier can be applied + Enabled bool + + //If true, this modifier can only be applied in an expansion game + //In the file, the value 100 represents expansion only + ExpansionOnly bool + + //If true, "Minion" will be displayed below the life bar of minions of the monster with this modifier + Xfer bool + + //If true, only usable by champion monsters + Champion bool + + //Unknown + FPick int + + //Names of monster types that cannot have this modifier + //Refer to Type in MonType.txt + Exclude1 string + Exclude2 string + + //Determines the frequency this modifier appears on champion monsters + //If empty, it will not appear on champions + ChampionPickFrequency int + ChampionPickFrequencyNightmare int + ChampionPickFrequencyHell int + + //Determines the frequency this modifier appears on random unique monsters + //If empty, it will not appear on random unique monsters + UniquePickFrequency int + UniquePickFrequencyNightmare int + UniquePickFrequencyHell int + + //FInit int: Unused +} + +//MonsterUniqueModifiers stores the MonsterUniqueModifierRecords +var MonsterUniqueModifiers map[string]*MonsterUniqueModifierRecord //nolint:gochecknoglobals // Currently global by design + +//MonsterUniqueModifierConstants contains constants from monumod.txt +//See [https://d2mods.info/forum/kb/viewarticle?a=161] for more info +//Can be accessed with indices from d2enum.MonUModConstIndex +var MonsterUniqueModifierConstants []int //nolint:gochecknoglobals + +//LoadMonsterUniqueModifiers loads MonsterUniqueModifierRecords into MonsterUniqueModifiers +func LoadMonsterUniqueModifiers(file []byte) { + MonsterUniqueModifiers = make(map[string]*MonsterUniqueModifierRecord) + MonsterUniqueModifierConstants = make([]int, 0, 34) + + d := d2common.LoadDataDictionary(file) + for d.Next() { + record := &MonsterUniqueModifierRecord{ + Name: d.String("uniquemod"), + ID: d.Number("id"), + Enabled: d.Bool("enabled"), + ExpansionOnly: d.Number("version") == 100, + Xfer: d.Bool("xfer"), + Champion: d.Bool("champion"), + FPick: d.Number("fpick"), + Exclude1: d.String("exclude1"), + Exclude2: d.String("exclude2"), + ChampionPickFrequency: d.Number("cpick"), + ChampionPickFrequencyNightmare: d.Number("cpick (N)"), + ChampionPickFrequencyHell: d.Number("cpick (H)"), + UniquePickFrequency: d.Number("upick"), + UniquePickFrequencyNightmare: d.Number("upick (N)"), + UniquePickFrequencyHell: d.Number("upick (H)"), + } + MonsterUniqueModifiers[record.Name] = record + if len(MonsterUniqueModifierConstants) < 34 { + MonsterUniqueModifierConstants = append(MonsterUniqueModifierConstants, (d.Number("constants"))) + } + } + + if d.Err != nil { + panic(d.Err) + } + + log.Printf("Loaded %d MonsterUniqueModifier records", len(MonsterUniqueModifiers)) +} diff --git a/d2common/d2enum/monumod_const_index.go b/d2common/d2enum/monumod_const_index.go new file mode 100644 index 00000000..cd6b2e43 --- /dev/null +++ b/d2common/d2enum/monumod_const_index.go @@ -0,0 +1,59 @@ +package d2enum + +// MonUModConstIndex is used as an index into d2datadict.MonsterUniqueModifierConstants +type MonUModConstIndex int + +const ( + //Champion chance + ChampionChance MonUModConstIndex = iota + + //MinionHPBonus is the HP bonus received by minions + MinionHPBonus + MinionHPBonusNightmare + MinionHPBonusHell + + //ChampionHPBonus is the HP bonus received by champions + ChampionHPBonus + ChampionHPBonusNightmare + ChampionHPBonusHell + + //UniqueHPBonus is the HP bonus received by random uniques + UniqueHPBonus + UniqueHPBonusNightmare + UniqueHPBonusHell + + //Attack rating and damage bonus of champions + ChampionAttackRatingBonus + ChampionDamageBonus + + //Attack rating and damage bonus of strong minions + StrongMinionAttackRatingBonus + StrongMinionDamageBonus + + //Minion elemental damage bonus + MinionElementalDamageMinBonus + MinionElementalDamageMinBonusNightmare + MinionElementalDamageMinBonusHell + + MinionElementalDamageMaxBonus + MinionElementalDamageMaxBonusNightmare + MinionElementalDamageMaxBonusHell + + //Minion elemental damage bonus + ChampionElementalDamageMinBonus + ChampionElementalDamageMinBonusNightmare + ChampionElementalDamageMinBonusHell + + ChampionElementalDamageMaxBonus + ChampionElementalDamageMaxBonusNightmare + ChampionElementalDamageMaxBonusHell + + //Unique elemental damage bonus + UniqueElementalDamageMinBonus + UniqueElementalDamageMinBonusNightmare + UniqueElementalDamageMinBonusHell + + UniqueElementalDamageMaxBonus + UniqueElementalDamageMaxBonusNightmare + UniqueElementalDamageMaxBonusHell +) diff --git a/d2common/d2resource/resource_paths.go b/d2common/d2resource/resource_paths.go index 28521cdd..333f6db0 100644 --- a/d2common/d2resource/resource_paths.go +++ b/d2common/d2resource/resource_paths.go @@ -177,32 +177,33 @@ const ( LevelMaze = "/data/global/excel/LvlMaze.txt" LevelSubstitutions = "/data/global/excel/LvlSub.txt" - ObjectDetails = "/data/global/excel/Objects.txt" - SoundSettings = "/data/global/excel/Sounds.txt" - ItemStatCost = "/data/global/excel/ItemStatCost.txt" - ItemTypes = "/data/global/excel/ItemTypes.txt" - QualityItems = "/data/global/excel/qualityitems.txt" - Runes = "/data/global/excel/runes.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" - AutoMap = "/data/global/excel/AutoMap.txt" - CubeRecipes = "/data/global/excel/cubemain.txt" - Skills = "/data/global/excel/skills.txt" - SkillDesc = "/data/global/excel/skilldesc.txt" - TreasureClass = "/data/global/excel/TreasureClassEx.txt" - States = "/data/global/excel/states.txt" - SoundEnvirons = "/data/global/excel/soundenviron.txt" - Shrines = "/data/global/excel/shrines.txt" - MonProp = "/data/global/excel/Monprop.txt" - ElemType = "/data/global/excel/ElemTypes.txt" - PlrMode = "/data/global/excel/PlrMode.txt" - PetType = "/data/global/excel/pettype.txt" - NPC = "/data/global/excel/npc.txt" + ObjectDetails = "/data/global/excel/Objects.txt" + SoundSettings = "/data/global/excel/Sounds.txt" + ItemStatCost = "/data/global/excel/ItemStatCost.txt" + ItemTypes = "/data/global/excel/ItemTypes.txt" + QualityItems = "/data/global/excel/qualityitems.txt" + Runes = "/data/global/excel/runes.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" + AutoMap = "/data/global/excel/AutoMap.txt" + CubeRecipes = "/data/global/excel/cubemain.txt" + Skills = "/data/global/excel/skills.txt" + SkillDesc = "/data/global/excel/skilldesc.txt" + TreasureClass = "/data/global/excel/TreasureClassEx.txt" + States = "/data/global/excel/states.txt" + SoundEnvirons = "/data/global/excel/soundenviron.txt" + Shrines = "/data/global/excel/shrines.txt" + MonProp = "/data/global/excel/Monprop.txt" + ElemType = "/data/global/excel/ElemTypes.txt" + PlrMode = "/data/global/excel/PlrMode.txt" + PetType = "/data/global/excel/pettype.txt" + NPC = "/data/global/excel/npc.txt" + MonsterUniqueModifier = "/data/global/excel/monumod.txt" // --- Animations ---