Closed collinsmith closed 5 years ago
I'm going to try and rewrite my stat and property list class as PropertyList
which wraps an IntMap
and uses statId | (param << 16)
as the key (stats are represented as their int
indexes and no longer as an enum). The max bits for param=16
and the max bits for statId=9
so this is well within the required bounds. I'm choosing to give statId
extra width to support additional stats, but I don't plan on adding many, if any. So far this is working out well, however I cannot sort the results (expected) and I'll need to generate a sorted list for the visual representation of the stats separately -- this will actually help when I aggregate multiple stats.
I'm not going to build it in yet, but I'm also considering how item updates will be made. Some stats have callbacks, e.g., charged item skills that add the skill to the user when equipped. With charged item skills, this is also a 2-way street because using the skill should modify the item stat, etc. I'm assuming too that something similar should be used if say an item is equipped and the players strength drops below the required strength, then item should appear red (equipped but unusable).
I mentioned this in https://github.com/collinsmith/diablo/issues/19#issuecomment-475806740
How I'm going to support
strModAllResistances All Resistances +%d
strModFireDamage +%d fire damage
strModFireDamageRange Adds %d-%d fire damage
strModColdDamage +%d cold damage
strModColdDamageRange Adds %d-%d cold damage
strModLightningDamage +%d lightning damage
strModLightningDamageRange Adds %d-%d lightning damage
strModMagicDamage +%d magic damage
strModMagicDamageRange Adds %d-%d magic damage
strModPoisonDamage +%d poison damage over %d seconds
strModPoisonDamageRange Adds %d-%d poison damage over %d seconds
strModMinDamage +%d damage
strModMinDamageRange Adds %d-%d damage
strModEnhancedDamage Enhanced damage
Since these are all visual only and will only be present in the item details, I think I will address this by formatting "fake" stats. I.e., when generating the item details I will omit the discrete stats and add the above aggregate stat instead (I may also ignore dgrp
because it's inconsistent and handle it with all the others). These may use a custom descfunc
and possibly even encoding
, or I can just generate the string manually. The concern with trying to hack it into a custom descfunc
or encoding
is that all of the multi-value props may not fit within 32-bits (they very well might). Another approach I might take is making a new aggregate stat class AggregateStat
which has 2+
children Stat
instances and a pre-determined string for multi-value or single value (Range
or no range variant), but in this case, all resistances
and all attributes
behaves differently when all the stats are different (they output as their super).
I just wanted to note that I realized with this approach _bytime
properties include all of their params within the value
field, therefore something that is really a param
such as time of day is in the value
field (i.e., two _bytime
properties with different times should remain discrete). My solution to this problem will be to hard-code the _bytime
properties as param=2 bits, value=20 bits
. I may not implement this immediately, but when I decide I want to support _bytime
properties, the workaround is here.
As for list aggregations for the display details:
A better way of thinking of this too is:
So because both magic and runeword property lists are same group, they are added, while the other remain discrete.
Support for socketed item attributes is on the docket to be added. For jewels this should be fairly straightforward as they have discrete magical properties, however gems and runes may provide a challenge. My current assumption for gems and runes is to assume they have no inherent magical properties and sort of add them on the fly depending on the item they are socketed into (these have different properties for weapons, armors/helms, shields). I will need to investigate a bit on how difficult this might be, because these items have their properties within gems.txt
which is not yet supported and looks like it relies on properties.txt
which is also not yet supported. Adding support for properties.txt
is a necessary prerequisite to properly supporting set bonuses (the gold bonus applied to the set as a whole).
I added descriptions for gems/runes. As far as displaying the selected property list in the parent item description, I think it might be possible to use the existing property lists (i.e., indexes 0-3
for weapon, armor, helm, shield
or whatever order is best) for the properties, but this is a bit more complicated since gems are "simple" items with no magical properties, and then these lists shouldn't display as if they were magical properties in the original item (they display as white
in the game).
20b84c8 added support for socketed items properties aggregating with their parents
I rewrote part of property list to more appropriately handle adding properties. The properties will generate randomly. This is largely untested because item generation is not yet implemented, but it should be a good start. This was necessary because gems and runes contain no inherent properties, so their properties must be generated on the fly and aggregated with their parent item (they are not random though, e.g., they give random(10,10)
to stats, which eval to just 10
).
Most properties work as expected, however there are at least 2 which do not. maxdamage
and secondary_maxdamage
both display the same value +%d to Maximum Damage
and since both are present on some items, the attribute appears twice. item_throw_maxdamage
should also appear, but that is a non-visible stat. I think for stats like these I will try aggregating all min damage and all max damage stats together --- after the min/max pairs have aggregated. I haven't seen any other oddballs.
I'm going to close this issue. I think everything has been covered on the visual end of item stats. I'll reopen if necessary.
Aggregations seem to be performed on a list-by-list basis, i.e., runeword properties will add to existing magic properties, but set properties will not aggregate with magic and (I assume, but untested) rune properties.
It seems that multiple copies of the same aggregateable skill in a single list will choose the last one. Some skills maintain their independence, e.g., charged skills will not overwrite if it's the same skill with a different level (i.e., different
param
value), but if the level and skill are the same (i.e., sameparam
value) the skill is overwritten. In this case, the charges will add to each other.I need to enumerate this relationship and investigate more, but my best guess is:
param
, this should be included in to the stat hash somehow, since thevalue
in this case determines the number of charges, level of the skill, etc, butparam
determines which skill, etc.To reiterate on the property lists:
+ to all resistances
). I think this will get generated with the item details and updating the item details (charge used, durability changed, etc) will re-generate this property list.So, item inherent properties list will be all the active list values added together, and then the algorithm will run to modify the item values all at once, so all the properties ED will add together and then when the lists are all added, ED will actually be calculated and applied to defense stat, etc.
TODO: how do things like aggregated charges work, since I'm guessing it subtracts a charge from one of the properties internally and then maybe re-generates the aggregate stat. TODO: I need to figure out and more clearly define the differentiation between the visual list aggregation and the actual item property aggregation, since all the item stats need to continue to be discrete internally for saving purposes, but I don't think it's realistic to calculate them on the fly every time a stat is retrieved at least visually