Thread: Multiple pvals
View Single Post
Old April 19, 2011, 22:28   #5
Angband Devteam member
Join Date: May 2007
Location: London, UK
Posts: 5,057
Magnate is on a distinguished road
Send a message via MSN to Magnate Send a message via Yahoo to Magnate
Originally Posted by PowerWyrm View Post
Here's the current code from obj_make:

/* Apply pvals */
for (i = 0; i < o_ptr->ego->num_pvals; i++)
if (!o_ptr->pval[i]) o_ptr->num_pvals++;
o_ptr->pval[i] += randcalc(o_ptr->ego->pval[i], level, RANDOMISE);

So base and ego pvals are added.

In object_pval_flags(), the flags on which the pvals are applied are ORed using of_union(). Let's examine the Elven Cloak of the Magi example again, using the latest txt files...

Base item: an Elven Cloak (L:2:STEALTH, L:1:SPEED)
Ego item: of the Magi (L:d2:1:INT, L:d3:1:STEALTH)

In object_prep(), the base pvals are assigned to the object pvals:
- pval 1: +2 to stealth
- pval 2: +1 to speed

In ego_apply_magic(), the ego pvals are assigned and added to the object pvals:
- pval 1: +1/+2 to int, making it +3/+4 to stealth/int
- pval 2: +1/+3 to stealth, making it +2/+4 to speed/stealth

The result:
an Elven Cloak of the Magi <+3/+4,+2/+4>
- +3/+4 to int
- +2/+4 to speed
- +5/+8 to stealth

If I'm correct, this is a hell of an ego item!

Sounds like a check must me made on the pval_flags when assigning the ego pvals to the object pvals:
- loop on ego pvals
- for each ego pval, get pval_flags
- for each pval_flag, check if it's already present on the object
- if yes, add the pval to the corresponding object pval
- if no, increase the number of object pvals and assign the pval to the new object pval

Some change must probably be made in object_pval_flags() to reflect this...

This means that object pvals must be an array of 2*MAX_PVALS, in case base item and ego item have a completely separate set of pval_flags...
Thank you for this analysis - I've had a niggling feeling for some time that something wasn't quite right here, and you've illustrated it very helpfully.

I agree with most of your prognosis, and will certainly check for existing pval flags during ego creation. I've opened ticket #1404 for this.

But on your last point, MAX_PVALS means exactly that. So once an object has all its pvals active (nonzero), any new flags will have to be attached to the pval closest to the desired outcome.

Let's take your Elven Cloak of the Magi example again: our base cloak has +2 stealth, +1 speed. First we add +1d2 INT as a third pval, then we add some more stealth to the first pval. Now let's say that the Magi ego has been given a third pval, +1d2 WIS. We have no more pvals to create, so we roll 1d2 and pick a pval closest to the result, and add the WIS flag to it.
Magnate is offline   Reply With Quote