Source talk:NetHack 3.4.3/src/artifact.c

From NetHackWiki
Revision as of 22:41, 11 November 2013 by Bejonas (talk | contribs)
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.

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;