PowerWyrm

September 7, 2011, 12:40

From scramble_artifact() in randart.c:

/* Set depth and rarity info according to power */

...

a_ptr->alloc_max = MIN(127, (ap * 4) / 5);

a_ptr->alloc_min = MIN(100, ((ap + 100) * 100 / max_power));

The problem here is that for ap less than 20, the result is a_ptr->alloc_max less than a_ptr->alloc_min.

From make_artifact():

/* Enforce maximum depth (strictly) */

if (a_ptr->alloc_max < p_ptr->depth) continue;

This means that low power random artifacts will have a really small depth range. If the item has a base level that is much higher, the random artifact may even never be generated.

Another problem, from make_artifact():

/* XXX XXX Enforce minimum "depth" (loosely) */

if (a_ptr->alloc_min > p_ptr->depth)

{

/* Get the "out-of-depth factor" */

int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

/* Roll for out-of-depth creation */

if (randint0(d) != 0) continue;

}

After enforcing that depth is lower than a_ptr->alloc_max, a rarity penalty is applied for out-of-depth randarts. With low ap randarts, since a_ptr->alloc_max is less than a_ptr->alloc_min, they are all considered out-of-depth! The out-of-depth factor will also increase as ap decreases... leading to less powerful randarts being generated... less often.

Fix: ensure that a_ptr->alloc_max is always greater than a_ptr->alloc_min

/* Set depth and rarity info according to power */

...

a_ptr->alloc_max = MIN(127, (ap * 4) / 5);

a_ptr->alloc_min = MIN(100, ((ap + 100) * 100 / max_power));

The problem here is that for ap less than 20, the result is a_ptr->alloc_max less than a_ptr->alloc_min.

From make_artifact():

/* Enforce maximum depth (strictly) */

if (a_ptr->alloc_max < p_ptr->depth) continue;

This means that low power random artifacts will have a really small depth range. If the item has a base level that is much higher, the random artifact may even never be generated.

Another problem, from make_artifact():

/* XXX XXX Enforce minimum "depth" (loosely) */

if (a_ptr->alloc_min > p_ptr->depth)

{

/* Get the "out-of-depth factor" */

int d = (a_ptr->alloc_min - p_ptr->depth) * 2;

/* Roll for out-of-depth creation */

if (randint0(d) != 0) continue;

}

After enforcing that depth is lower than a_ptr->alloc_max, a rarity penalty is applied for out-of-depth randarts. With low ap randarts, since a_ptr->alloc_max is less than a_ptr->alloc_min, they are all considered out-of-depth! The out-of-depth factor will also increase as ap decreases... leading to less powerful randarts being generated... less often.

Fix: ensure that a_ptr->alloc_max is always greater than a_ptr->alloc_min