ftp.nice.ch/pub/next/games/strategic/NetHack.s.tar.gz#/NetHackSource/src/artifact.c

This is artifact.c in view mode; [Download] [Up]

/*	SCCS Id: @(#)artifact.c	3.0	88/07/27
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed.  See license for details. */

#include "hack.h"

#ifdef NAMED_ITEMS

#include "artifact.h"

#ifndef OVLB

OSTATIC const struct artifact artilist[];

#else /* OVLB */

/* the artifacts (currently weapons only) */
XSTATIC const struct artifact artilist[] = {

#define	    NO_ATTK	{ 0, 0, 0, 0 }

{ LONG_SWORD,	 "Excalibur",	(SPFX_NOGEN | SPFX_SEEK | SPFX_DEFN |
								SPFX_SEARCH), 0,
  { 0, AD_PHYS, 5, 10 }, { 0, AD_DRLI, 0, 0}, A_LAW, 'K' },

{ KATANA,	 "Snickersnee",	SPFX_RESTR, 0,
  { 0, AD_PHYS, 0, 8 }, NO_ATTK, A_LAW, 'S' },

/*	Ah, never shall I forget the cry, 
 *		or the shriek that shrieked he,
 *	As I gnashed my teeth, and from my sheath
 *		I drew my Snickersnee!
 *
 *		--Koko, Lord high executioner of Titipu
 *		  (From Sir W.S. Gilbert's "The Mikado")
 */

{ AXE,		 "Cleaver",	SPFX_RESTR, 0,
  { 0, AD_PHYS, 3, 12 }, NO_ATTK, A_CHAOS, 0 },

#ifdef TOLKIEN
{ ORCISH_DAGGER, "Grimtooth",	SPFX_RESTR, 0,
  { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
#else
{ DAGGER,	 "Grimtooth",	SPFX_RESTR, 0,
  { 0, AD_PHYS, 2, 6 }, NO_ATTK, A_CHAOS, 0 },
#endif

/*  Special purpose swords - various types */

{ TWO_HANDED_SWORD, "Orcrist",	SPFX_DFLAG2, M2_ORC,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 'E' },

#ifdef TOLKIEN
{ ELVEN_DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DFLAG2), M2_ORC,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
#else
{ DAGGER,	 "Sting",	(SPFX_WARN | SPFX_DFLAG2), M2_ORC,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },
#endif

{ LONG_SWORD,	 "Frost Brand", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
  { 0, AD_COLD, 5, 0 }, { 0, AD_COLD, 0, 0 }, A_NEUTRAL, 0 },

{ LONG_SWORD,	 "Fire Brand",	(SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0,
  { 0, AD_FIRE, 5, 0 }, { 0, AD_FIRE, 0, 0 }, A_NEUTRAL, 0 },

/* Stormbringer only has a 2 because it can drain a level, providing 8 more */
{ BROADSWORD,	 "Stormbringer", (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN |
								SPFX_DRLI), 0,
  { 0, AD_DRLI, 5, 2 }, { 0, AD_DRLI, 0, 0 }, A_CHAOS, 0 },

{ LONG_SWORD,	 "Sunsword",	(SPFX_RESTR | SPFX_DFLAG2), M2_UNDEAD,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },

{ BROADSWORD,	 "Dragonbane",	(SPFX_RESTR | SPFX_DCLAS), S_DRAGON,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },

{ LONG_SWORD,	 "Demonbane",	(SPFX_RESTR | SPFX_DFLAG2), M2_DEMON,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },

/* A silver weapon would be appropriate, if we had one. */
{ LONG_SWORD,	 "Werebane",	(SPFX_RESTR | SPFX_DFLAG2), M2_WERE,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },

{ LONG_SWORD,	 "Giantslayer", (SPFX_RESTR | SPFX_DFLAG2), M2_GIANT,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_NEUTRAL, 0 },

/* Another interesting weapon would be the dwarven hammer or axe with the
 * boomerang-like power of returning to the wielder's hand, if the code
 * were written to add such an ability.
 */
{ WAR_HAMMER, "Ogresmasher",	(SPFX_RESTR | SPFX_DCLAS), S_OGRE,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },

{ WAR_HAMMER, "Mjollnir",	(SPFX_RESTR | SPFX_ATTK),  0,
  { 0, AD_ELEC, 5, 24 }, NO_ATTK, A_LAW, 'V' }, /* Mjo:llnir */

{ MORNING_STAR,	 "Trollsbane", (SPFX_RESTR | SPFX_DCLAS), S_TROLL,
  { 0, AD_PHYS, 5, 0 }, NO_ATTK, A_LAW, 0 },

/*	ARRAY TERMINATOR	*/
{ 0,  "", 0, 0, NO_ATTK, NO_ATTK, 0, 0 }
};

const int artifact_num = SIZE(artilist);

/* this array gets saved / restored - thus not static */
boolean artiexist[SIZE(artilist)];

#endif /* OVLB */

OSTATIC const struct artifact *FDECL(get_artifact, (struct obj *));
OSTATIC int FDECL(spec_applies, (const struct artifact *, struct permonst *));

#ifdef OVLB

/* zero out the artifact exist list */
void
init_exists()
{
	int i;

	for(i = 0; i < SIZE(artilist); i++)
		artiexist[i] = 0;
}

void
mkartifact(otmp1)
struct obj **otmp1;
{
	register const struct artifact *artif;
	register struct obj *otmp = *otmp1;
	register int n = 0, m;

	for(artif = artilist,m = 0; artif->otyp; artif++,m++)
	    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
	       !artiexist[m]) n++;

	if (n) {
		n = rnd(n);
		for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
		    if(otmp->otyp == artif->otyp && !(artif->spfx & SPFX_NOGEN) &&
		       !artiexist[m]) n--;
		    if (n > 0) {
			artif++;
			m++;
		    }
		}

		if(artif->otyp) {
		    *otmp1 = oname(otmp, artif->name, 0);
		    artiexist[m] = TRUE;
		}
	}
}

#endif /* OVLB */
#ifdef OVL0

XSTATIC const struct artifact *
get_artifact(otmp)
struct obj *otmp;
{
	register const struct artifact *artif;

	if(otmp)
	    if(strlen(ONAME(otmp)))
		for(artif = artilist; artif->otyp; artif++)
		    if(artif->otyp == otmp->otyp &&
		       !strcmp(ONAME(otmp), artif->name))
			    return artif;
	return((struct artifact *)0);
}

#endif /* OVL0 */
#ifdef OVLB

boolean
is_artifact(otmp)
struct obj *otmp;
{
	return(get_artifact(otmp) != (struct artifact *)0);
}

boolean
exist_artifact(otmp, name)
register struct obj *otmp;
register const char *name;
{
	register const struct artifact *artif;
	register boolean *arex;

	if(otmp && strlen(name))
	    for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
		if(artif->otyp == otmp->otyp &&
		   !strcmp(name, artif->name) &&
		   *arex)
		    return TRUE;
	return FALSE;
}

void
artifact_exists(otmp, name, mod)
register struct obj *otmp;
register const char *name;
register boolean mod;
{
	register const struct artifact *artif;
	register boolean *arex;

	if(otmp && strlen(name))
	    for(artif = artilist,arex = artiexist; artif->otyp; artif++,arex++)
		if(artif->otyp == otmp->otyp &&
		   !strcmp(name, artif->name))
		    *arex = mod;
	return;
}

#endif /* OVLB */
#ifdef OVL0

boolean
spec_ability(otmp, abil)
struct obj *otmp;
unsigned abil;
{
	const struct artifact *arti = get_artifact(otmp);
	
	return(arti && (arti->spfx & abil));
}

#endif /* OVL0 */
#ifdef OVLB

int
restr_name(otmp, name)	/* returns 1 if name is restricted for otmp->otyp */
register struct obj *otmp;
register char	*name;
{
	register const struct artifact *artif;

	if(!strlen(name)) return(0);

	for(artif = artilist; artif->otyp; artif++)
	    if(artif->otyp == otmp->otyp)
		if(artif->spfx & (SPFX_NOGEN | SPFX_RESTR))
		    if(!strcmp(artif->name, name)) return(1);

	return(0);
}

# if defined(THEOLOGY) && defined(ALTARS)
struct obj *
mk_aligned_artifact(align)
unsigned align;
{
	register const struct artifact *artif;
	register struct obj *otmp;
	register int n = 0, m;

	for(artif = artilist,m = 0; artif->otyp; artif++,m++)
	    if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
		if (pl_character[0] == artif->class) {
		    n = 0;
		    break;
		} else n++;
	if (n) {
		n = rnd(n);
		for(artif = artilist,m = 0; artif->otyp && n > 0; ) {
		    if(align == artif->align && !(artif->spfx & SPFX_NOGEN) && !artiexist[m])
			n--;
		    if (n > 0) {
			artif++;
			m++;
		    }
		}
	}
	if(artif->otyp) {
		otmp = mksobj((int)artif->otyp, FALSE);
		otmp = oname(otmp, artif->name, 0);
		artiexist[m] = TRUE;
		return (otmp);
	}
	return ((struct obj *) 0);
}
# endif

int
defends(adtyp, otmp)
register int adtyp;
register struct obj *otmp;
{
	register const struct artifact *weap;

	if(weap = get_artifact(otmp))
		return(weap->defn.adtyp == adtyp);
	return(0);
}

XSTATIC int
spec_applies(weap, ptr)
register const struct artifact *weap;
struct permonst *ptr;
{
	if(!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK)))
	    return(0);

	if(weap->spfx & SPFX_DMONS)
	    return((ptr == &mons[(int)weap->mtype]));
	else if(weap->spfx & SPFX_DCLAS)
	    return((weap->mtype == ptr->mlet));
	else if(weap->spfx & SPFX_DFLAG1)
	    return((ptr->mflags1 & weap->mtype) != 0L);
	else if(weap->spfx & SPFX_DFLAG2)
	    return((ptr->mflags2 & weap->mtype) != 0L);
	else if(weap->spfx & SPFX_ATTK) {
	    switch(weap->attk.adtyp) {
		case AD_FIRE:	return(!resists_fire(ptr));
		case AD_COLD:	return(!resists_cold(ptr));
		case AD_ELEC:	return(!resists_elec(ptr));
		case AD_DRLI:	return(!resists_drli(ptr));
		case AD_STON:	return(!resists_ston(ptr));
		default:	impossible("Weird special attack for '%s'",
					   weap->name);
	    }
	}
	return(0);
}

#endif /* OVLB */
#ifdef OVL1

int
spec_abon(otmp, ptr)
struct obj *otmp;
struct permonst *ptr;
{
	register const struct artifact *weap;

	if((weap = get_artifact(otmp)))
		if(spec_applies(weap, ptr))
		    return((weap->attk.damn) ? rnd((int)weap->attk.damn) : 0);
	return(0);
}

int
spec_dbon(otmp, ptr, tmp)
register struct obj *otmp;
register struct permonst *ptr;
register int	tmp;
{
	register const struct artifact *weap;

	if((weap = get_artifact(otmp)))
		if(spec_applies(weap, ptr))
		    return((weap->attk.damd) ? rnd((int)weap->attk.damd) : tmp);
	return(0);
}

#endif /* OVL1 */

#endif /* NAMED_ITEMS */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.