Spell Damage Calculation

Questions, Explanations, Howtos Mines Malingerer

Posts: 46

Joined: Tuesday, 21st December 2010, 10:13

Location: Japan Spell Damage Calculation

So I was checking out zap-data.h
Spell data looks like this..
Code:
{
ZAP_THROW_FLAME,
"puff of flame",
50,
new dicedef_calculator<2, 4, 1, 10>,
new tohit_calculator<8, 1, 10>,
new dicedef_calculator<3, 5, 1, 40>,
new tohit_calculator<25, 1, 40>,
RED,
false,
BEAM_FIRE,
DCHAR_FIRED_ZAP,
true,
false,
false,
2
}

So as far as I can tell the damage a player will deal with this spell is:
Code:
new dicedef_calculator<2, 4, 1, 10>

At max power:
2d (4 + (maxpower= 50) * 1 / 10)
2d9
2-18

Now if I look at a spell like Poison arrow
Code:
new calcdice_calculator<4, 15, 1, 1>,

At max power:
4d(15 + (maxpower= 200) *1 / 1)
4d215
4-860

Clearly poison arrow doesn't do a maximum of 860 damage. What am I missing here? There seems to be a dicedef_calculator and calcdice_calculator but I don't see what the difference is between them.

Ziggurat Zagger

Posts: 8659

Joined: Sunday, 5th May 2013, 08:25

Re: Spell Damage Calculation

dicedef_calculator<dice, constant, numerator, denominator> results in (dice)d(constant+power*numerator/denominator)
calcdice_calculator<dice, constant, numerator, denominator> results in (dice)d((constant+power*numerator/denominator)/dice)

The idea of calcdice_calculator and calc_dice is that you give them a maximum damage amount (constant+power*numerator/denominator) and that gets spread across some number of dice. So increasing the number of dice in a calcdice_calculator only increases the damage a little bit, but it makes it much more consistent.

Both dicedef_calculators and calcdice_calculators randomly round the die sizes, but for the entire roll instead of individually per-die. So if one of the above formulas gives you 6d9.3, it'll roll 6d9 70% of the time and 6d10 the other 30%. This does mean that changing the number of dice in a calcdice_calculator changes the maximum damage slightly.

There's no particular reason other than legacy that some zaps use dicedef_calculator and others use calcdice_calculator, since you can easily get the same result from either one. Standardizing it would make it a lot easier to compare zaps though...

For this message the author duvessa has received thanks:
chrysalis Mines Malingerer

Posts: 46

Joined: Tuesday, 21st December 2010, 10:13

Location: Japan

Re: Spell Damage Calculation

Found it in random.cc
The code is really unintuitive... Thanks for clearing it up for me though. Code:
int dice_def::roll() const
{
return roll_dice(num, size);
}

dice_def calc_dice(int num_dice, int max_damage)
{
dice_def ret(num_dice, 0);

if (num_dice <= 1)
{
ret.num  = 1;
ret.size = max_damage;
}
else if (max_damage <= num_dice)
{
ret.num  = max_damage;
ret.size = 1;
}
else
ret.size = div_rand_round(max_damage, num_dice);

return ret;
}

// Calculates num/den and randomly adds one based on the remainder.
// [floor(num/den), ceil(num/den)]
int div_rand_round(int num, int den)
{
int rem = num % den;
if (rem)
return num / den + (random2(den) < rem);
else
return num / den;
}

// Converts a double to an integer by randomly rounding.
// Currently does not handle negative inputs.
int rand_round(double x)
{
ASSERT(x >= 0);
return int(x) + decimal_chance(fmod(x, 1.0));
}

int div_round_up(int num, int den)
{
return num / den + (num % den != 0);
}