Source talk:NetHack 3.4.3/src/artifact.c

From NetHackWiki
Revision as of 22:53, 11 November 2013 by Bejonas (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

On the implementation

The artifact weapon handling code is one of the most tangled pieces of code. Here are some findings.

The bonuses of artifacts are defined partly by artilist Artilist.h. This is an array of struct artifact structures. This structure has a struct attack attk field whose members are used in a way completely unlike how struct attack is used for monster descriptions. In this struct attack, the adtyp field tells both what type of elemental damage the bonus damage deals, and how a monster can resist the bonus damage; the damn field gives the to-hit bonus, and the damd field gives the damage bonus.

The to-hit bonus applies against any monsters, and is 1dX where X is the previously mentioned damn field.

The damage bonus applies only to particular monsters, and either adds 1dY extra damage where Y is the damd field, or doubles the normal damage that would be dealt by the weapon (if the damd field is zero). This is handled in artifact.c:artifact_hit. There's special handling for artifacts that drain life or behead or bisect.

Magicbane gets extra special bonuses in addition to the normal damage bonus code path. This handles both the effects and the extra damage for the scare, confuse, stun, cancel, probe bonuses.

One crazy part of this code is the action at a distance with the spec_dbon_applies static boolean variable of artifact.c. This variable tells whether the current weapon hit with an artifact can apply the special attack to the monster it's hit. The value of this variable is computed by artifact.c:spec_dbon, and is checked in artifact.c:artifact_hit which calls spec_dbon before. In case of Magicbane, spec_dbon_applies gets decided from a monmr roll, but this monmr roll doesn't go through the zap.c:resist function and doesn't add the level difference bonus unlike most monmr checks. (If the player is attacked, there is no monmr check, you resist if you have MR.) If spec_dbon_applies, Magicbane deals an extra 1d4 damage, and the special attacks are somewhat more likely. The cancel and scare effects have an extra monmr check (MR check for the player), which can negate the cancel or scare effect but not the associated damage. This latter monmr check is a normal one going through zap.c:resist, and so gets the level bonuses from the defender's level and constant 10 (normal for weapons) used as the attacker's level.

Another crazy part is well known because of the comment in weapon.c:dmgval:

           /* if the weapon is going to get a double damage bonus, adjust
              this bonus so that effectively it's added after the doubling */
           if (bonus > 1 && otmp->oartifact && spec_dbon(otmp, mon, 25) >= 25)
               bonus = (bonus + 1) / 2;