Warheck wrote
Good researching! Pent, your link from post #8 (chao's quote) provides some tantalizing clues as to the workings of the danger system. Holybanana hints at the fact that activated states are taken into account during monster generation. I wonder what else is taken into account?
I intended to respond to this with a short message pointing you in the direction of possible information, but my curiosity got the better of me, and rather than write a 30 second response as I originally planned, I've spent the last 4-5 hours searching through and poring over the code and compiling a document on what I've discovered.
It isn't nearly complete, but I need a break (and sleep), so here's what I've got (attached as .txt as well, for those who want to read it without the wonky colors):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Danger System
of
Iter Vehemens ad Necem
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Organization is (ideally) from the ground up, such that the document can be read straight
through without having to skip around for definitions.
For simplicity's sake, when possible, in character:: member functions, the calling character shall
be assumed to be the player (a note will be made upon each necessary suspension of this assumption).
~ GetTimeToDie
char.cpp, line 5702:
double character::GetTimeToDie(ccharacter* Enemy, int Damage, double ToHitValue, truth AttackIsBlockable, truth UseMaxHP) const
bodypart.cpp, line 1507:
double bodypart::GetTimeToDie(int Damage, double ToHitValue, double DodgeValue, truth AttackIsBlockable, truth UseMaxHP) const
Various damage calculations are performed. Returns minimum hits required to kill character.
~ GetTimeToKill
nonhuman.cpp, line 349:
double nonhumanoid::GetTimeToKill(ccharacter* Enemy, truth UseMaxHP) const
human.cpp, line 1924:
double humanoid::GetTimeToKill(ccharacter* Enemy, truth UseMaxHP) const
/* Returns the average number of APs required to kill Enemy */
TimeToKill = AttackStyles / Effectivity
AttackStyles is incremented for each type of attack the enemy has: Arm-based attacks,
Leg-based attacks, and Head-based attacks. For each AttackStyle an addition to Effectivity is
calculated in part by GetTimeToDie(), which seems to be where equipment actually factors
into danger calculations (as GetTimeToDie() performs various damage calculations).
If character is hasted Effectivity is doubled.
If character is slowed Effectivity is halved.
Should AttackStyles be equal to 0, a value of 10,000,000 will be returned instead of AttackStyles/Effectivity.
~ Limit
felibdef.h, line 68:
inline type Limit(type Value, type Minimum, type Maximum)
{ return Value >= Minimum ? Value <= Maximum ? Value : Maximum : Minimum; }
If I interpret this properly, then this is equivalent to:
if (Value >= Minimum) {
if (Value <= Maximum)
return Value;
else
return Maximum;
}
else
return Minimum;
or, more simply:
if (Value < Minimum)
return Minimum;
if (Value > Maximum)
return Maximum;
else
return Value;
In essence, if the result is below the minimum, it returns the minimum, and the same should
the result be over the maximum. Should the value be within the limits it is returned intact.
~ Relative Danger
char.cpp, live 5732:
double character::GetRelativeDanger(ccharacter* Enemy, truth UseMaxHP) const
/*calculates relative danger of Enemy*/
TimeToKill is used to calculate the initial Danger, via dividing the enemy's time to
kill the player by the player's time to kill the enemy.
If Enemy's movement AP requirement is greater than that of the player, Danger is multiplied by 1.25.
In the opposite case, Danger is multiplied by 0.80.
If the Enemy is not visible, Danger is halved (if Enemy is the player it is multiplied by 0.2).
If the Player is not visible to the Enemy, Danger is multiplied by 5 (if the caller is a non-player, Danger is doubled).
##This doesn't make sense; shouldn't the opposite be the case? GetTimeToDie may be the key here,
##since being invisible to the other party should heavily affect the ToHitValue.
If the caller is NOT the player, and has an INT of less than 10, Danger is multiplied by 0.80.
If the Enemy has an intelligence of less than 10 (and is NOT the player), Danger is multiplied by 1.25.
Returns Limit fuction of Danger with a minimum of 0.001, and maximum of 1000.
~ Danger Map
Map containing danger values of characters
~ Naked Danger
Component of Danger Map
~ Equipped Danger
Component of Danger Map
~ Knowledge of the Ancients
Option D (Character Danger Values) displays three stats for each character:
Danger (Relative Danger (to player)*1000), NGM (Naked Danger*1000), and EGM (Equipped Danger*1000)
~ InitDangerMap
?
~ CalculateNextDanger
?
~ Danger Iterator
?
~ GetMinDifficulty
~ BalancedCreateMonster
proto.cpp, line 22:
character* protosystem::BalancedCreateMonster()
This is the most interesting part: the part where the game actually determines what critters to spawn!
I'm too tired to sort it out mentally at the moment, but you can take a look at BalancedCreateMonster() in
proto.cpp for reference. Also just below it is BalancedCreateItem(), which I haven't looked at at all, but may contain some interesting stuff as well.