Open youbetterdont opened 5 years ago
Good catch. Did some testing and you're exactly right. The set bits correspond with how many items of that set need to be worn to get that bonus, and also with the values of the aprop
fields in SetItems.txt.
If the bits are numbered 54321:
Examples:
aprop3
field setaprop1
-aprop5
fields setaprop2
and aprop4
fields setYes you're right, the data should be there, I know I figured out the rules like two years ago when I did this, I can't remember exactly but there's a flag (the one you linked) that tells us how many lists of magical properties to read, and the lists are read here.
I think the thing left is to figure out how many set pieces you have to wear to get the bonus, so we can apply in the frontend on the Armory for example, to calculate the correct bonuses.
@nokka, are you saying you do read that information out somewhere? My comment was that not only does that 5-bit number tell you how many lists to read, it also tells you which bonuses to apply. It looks like @squeek502 confirmed this.
I did manage to figure out how to apply the green-text set bonuses without this extra piece of information, but it does require a bit more work. You can take a look here if you're curious. I still need to apply the partial and full set bonuses (gold text), but this should be pretty easy using the Sets.txt->Properties.txt->ItemStatCost.txt lookup. I assume these properties are not in the d2s file, and it doesn't look like the set ID itself is either ("Tal Rasha's Wrappings").
If I get this all working, I can let you know. Maybe there's an easy way to make it work with the armory.
@squeek502, one other thing to check is how this field works with the super special set item Civerb's Ward. That one has bonuses that depend on equipping specific other set items (not how many total pieces are worn). I believe this is the only item that works this way, so it's more of a curiosity. Maybe mod makers use this rare feature more.
My guess is it works the same way in that it corresponds to the aprop fields of SetItems.txt. Still, it seems there's no avoiding a lookup in the *.txt files.
d2s currently doesn't put that info in the json. Made a PR for that: https://github.com/nokka/d2s/pull/6
@youbetterdont I haven't tested to see what the bits are set to for Civerb's Ward, but judging from SetItems.txt, it's probably a hardcoded special case in the code, since there's nothing that separates it in SetItems.txt (one possible bonus is in aprop1
, one is in aprop2
). My PR doesn't handle that special case.
That's a nice solution. So is my understanding correct that there is no reference to the set itself, nor is there any information about the gold-text set bonuses in the d2s file?
As far as the add_func=1 case, I bet the bit positions are tied to specific set pieces rather than the number of set items equipped, but this doesn't really impact anything on the file parsing side. We can always reconstruct the bitmask by placing a 1 in the bit positions specified by the new set_attributes_req list.
there is no reference to the set itself, nor is there any information about the gold-text set bonuses in the d2s file
Correct
add_func=1
Ah, I see, yeah that does differentiate Civerb's Ward in SetItems.txt, didn't notice that before. Will do more testing on that.
EDIT: Here's a description of add_func=1: https://d2mods.info/forum/kb/viewarticle?a=348 (see the Appendix at the bottom)
Confirmed that the bits are set the same with add_func 1 and 2. Civerb's Ward has the 5 bits set as: 00011
. Not sure how it would be best for d2s to account for that.
I don’t think d2s can account for it. Seems like a lookup into the txt files is unavoidable anyway given that we don’t have a set ID or the gold text properties. I bet the bit positions are ordered consistently with the set items in SetItems.txt. That is, the LSB in this case is civerb’s Amulet, and the next bit is civerb’s scepter. The scheme you already implemented should still work fine. We should just think of the numbers representing set item offsets instead of total number of items worn.
If we want to integrate this with the armory, what is the best way to do that? The code I’m working on could produce a modified JSON file after the *.txt lookups. Not sure if combing through the game data files is in the scope of d2s.
See the link I edited into a previous comment for a detailed description of add_func=1 (see appendix at the bottom). Some possible things that d2s could do (in addition to whats in #6):
[1, 2]
(set IDs of the amulet and scepter respectively)set_attributes_req
for both, and have a second variable that provides the add_func
for the item, so then users would switch how they use set_attributes_req
depending on that second var.As for the overall set bonuses and set names, it might be consistent to hard-code them into d2s and provide them in their own key in the json when applicable. That would be pretty similar to e.g. socketables.go, as otherwise the rune bonuses would require a .txt lookup as well.
Thanks for the link. I've actually been referring to these item guides quite frequently. My thoughts:
Add a second companion array that gets filled with set IDs of the items required for those bonuses. So, for Civerb's Ward that'd look like [1, 2] (set IDs of the amulet and scepter respectively)
I think this information may already be here and encoded in the bit positions, but it's hard to confirm this given that this one item is the only exception.
Use set_attributes_req for both, and have a second variable that provides the add_func for the item, so then users would switch how they use set_attributes_req depending on that second var.
This would require a lookup to SetItems.txt, right? If you do this lookup, then you could just modify the set_attributes directly.
Provide the 5 bits directly and let the user handle it
This information is already in the scheme you've chosen if you think of the numbers in the list as bit positions instead of items required.
As for the overall set bonuses and set names, it might be consistent to hard-code them into d2s and provide them in their own key in the json when applicable. That would be pretty similar to e.g. socketables.go, as otherwise the rune bonuses would require a .txt lookup as well.
Is there a good reason to avoid the lookups? Hard-coding will make d2s less portable to other mods for example.
I think this information may already be here and encoded in the bit positions, but it's hard to confirm this given that this one item is the only exception.
It is, but only by accident. If it was the amulet that used add_func=1 instead of the shield, then the required set IDs would be [0, 2]
(shield and scepter respectively), but the bits would still look like 00011
.
This information is already in the scheme you've chosen if you think of the numbers in the list as bit positions instead of items required.
True, but if the user is expected to need the bit position info, then it'd make more sense to provide it in a more usable format instead of having to do a very non-obvious transformation (bits |= 1 << (set_attributes_req[i] - 2)
for i=0 to 4).
Is there a good reason to avoid the lookups? Hard-coding will make d2s less portable to other mods for example.
d2s is already extremely coupled to vanilla D2. It hard-codes language strings, ItemStatCost.txt values, rune bonuses, item stats like weapon damage, weapon/armor/stackable item codes, etc, etc. Decoupling it while providing the same json output would take a pretty extensive rewrite. For example, reading items in general needs info from Armor.txt, Weapons.txt, Misc.txt, and ItemStatCost.txt.
Gotcha. I just started working with the d2s JSON output, so I’m still new to this! I really like the output format. Super easy to work with.
https://github.com/nokka/d2s/blob/db00d42b850e00cdb96e2e65de85b7ff06f9b787/item.go#L458
Is there a chance there could be more info lurking in this 5 bit value? The decoding appears to just be a count of the number of ones in the binary number. The position of the bits may indicate how many set pieces are needed to activate the bonus, for example. I was thinking about the best way to get the set bonuses working, and this would be some nice info to have if that's how it works. I might try to dig through the binary myself at some point, but thought I'd ask here first.
--M81 from slash discord