rework artifact.c to not use null pointers at all
This commit is contained in:
+55
-29
@@ -14,17 +14,20 @@
|
|||||||
* the contents, just the total size.
|
* the contents, just the total size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define get_artifact(o) \
|
static struct artifact *get_artifact(struct obj *) NONNULL; /* never returns null */
|
||||||
(((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] : 0)
|
|
||||||
|
|
||||||
static boolean bane_applies(const struct artifact *, struct monst *);
|
/* #define get_artifact(o) \
|
||||||
static int spec_applies(const struct artifact *, struct monst *);
|
(((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] \
|
||||||
|
: &nonartifact) */
|
||||||
|
|
||||||
|
static boolean bane_applies(const struct artifact *, struct monst *) NONNULLARG12;
|
||||||
|
static int spec_applies(const struct artifact *, struct monst *) NONNULLARG12;
|
||||||
static int invoke_ok(struct obj *);
|
static int invoke_ok(struct obj *);
|
||||||
static int arti_invoke(struct obj *);
|
static int arti_invoke(struct obj *);
|
||||||
static boolean Mb_hit(struct monst * magr, struct monst *mdef,
|
static boolean Mb_hit(struct monst * magr, struct monst *mdef,
|
||||||
struct obj *, int *, int, boolean, char *);
|
struct obj *, int *, int, boolean, char *);
|
||||||
static unsigned long abil_to_spfx(long *);
|
static unsigned long abil_to_spfx(long *) NONNULLARG1;
|
||||||
static uchar abil_to_adtyp(long *);
|
static uchar abil_to_adtyp(long *) NONNULLARG1;
|
||||||
static int glow_strength(int);
|
static int glow_strength(int);
|
||||||
static boolean untouchable(struct obj *, boolean);
|
static boolean untouchable(struct obj *, boolean);
|
||||||
static int count_surround_traps(coordxy, coordxy);
|
static int count_surround_traps(coordxy, coordxy);
|
||||||
@@ -64,6 +67,8 @@ static xint16 artidisco[NROFARTIFACTS];
|
|||||||
* and restored but that is done through this file so they can be local.
|
* and restored but that is done through this file so they can be local.
|
||||||
*/
|
*/
|
||||||
static const struct arti_info zero_artiexist = {0}; /* all bits zero */
|
static const struct arti_info zero_artiexist = {0}; /* all bits zero */
|
||||||
|
/* fields in nonartifact don't matter, just its distinct address */
|
||||||
|
static struct artifact nonartifact = {0};
|
||||||
|
|
||||||
static void hack_artifacts(void);
|
static void hack_artifacts(void);
|
||||||
static boolean attacks(int, struct obj *);
|
static boolean attacks(int, struct obj *);
|
||||||
@@ -427,7 +432,7 @@ spec_ability(struct obj *otmp, unsigned long abil)
|
|||||||
{
|
{
|
||||||
const struct artifact *arti = get_artifact(otmp);
|
const struct artifact *arti = get_artifact(otmp);
|
||||||
|
|
||||||
return (boolean) (arti && (arti->spfx & abil) != 0L);
|
return (boolean) (arti != &nonartifact && (arti->spfx & abil) != 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* used so that callers don't need to known about SPFX_ codes */
|
/* used so that callers don't need to known about SPFX_ codes */
|
||||||
@@ -447,7 +452,7 @@ arti_reflects(struct obj *obj)
|
|||||||
{
|
{
|
||||||
const struct artifact *arti = get_artifact(obj);
|
const struct artifact *arti = get_artifact(obj);
|
||||||
|
|
||||||
if (arti) {
|
if (arti != &nonartifact) {
|
||||||
/* while being worn */
|
/* while being worn */
|
||||||
if ((obj->owornmask & ~W_ART) && (arti->spfx & SPFX_REFLECT))
|
if ((obj->owornmask & ~W_ART) && (arti->spfx & SPFX_REFLECT))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -470,7 +475,8 @@ shade_glare(struct obj *obj)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
/* non-silver artifacts with bonus against undead also are effective */
|
/* non-silver artifacts with bonus against undead also are effective */
|
||||||
arti = get_artifact(obj);
|
arti = get_artifact(obj);
|
||||||
if (arti && (arti->spfx & SPFX_DFLAG2) && arti->mtype == M2_UNDEAD)
|
if (arti != &nonartifact && (arti->spfx & SPFX_DFLAG2)
|
||||||
|
&& arti->mtype == M2_UNDEAD)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
/* [if there was anything with special bonus against noncorporeals,
|
/* [if there was anything with special bonus against noncorporeals,
|
||||||
it would be effective too] */
|
it would be effective too] */
|
||||||
@@ -535,7 +541,7 @@ attacks(int adtyp, struct obj *otmp)
|
|||||||
{
|
{
|
||||||
const struct artifact *weap;
|
const struct artifact *weap;
|
||||||
|
|
||||||
if ((weap = get_artifact(otmp)) != 0)
|
if ((weap = get_artifact(otmp)) != &nonartifact)
|
||||||
return (boolean) (weap->attk.adtyp == adtyp);
|
return (boolean) (weap->attk.adtyp == adtyp);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -547,7 +553,7 @@ defends(int adtyp, struct obj *otmp)
|
|||||||
|
|
||||||
if (!otmp)
|
if (!otmp)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ((weap = get_artifact(otmp)) != 0)
|
if ((weap = get_artifact(otmp)) != &nonartifact)
|
||||||
return (boolean) (weap->defn.adtyp == adtyp);
|
return (boolean) (weap->defn.adtyp == adtyp);
|
||||||
if (Is_dragon_armor(otmp)) {
|
if (Is_dragon_armor(otmp)) {
|
||||||
int otyp = otmp->otyp;
|
int otyp = otmp->otyp;
|
||||||
@@ -596,7 +602,7 @@ defends_when_carried(int adtyp, struct obj *otmp)
|
|||||||
{
|
{
|
||||||
const struct artifact *weap;
|
const struct artifact *weap;
|
||||||
|
|
||||||
if ((weap = get_artifact(otmp)) != 0)
|
if ((weap = get_artifact(otmp)) != &nonartifact)
|
||||||
return (boolean) (weap->cary.adtyp == adtyp);
|
return (boolean) (weap->cary.adtyp == adtyp);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -610,7 +616,7 @@ protects(struct obj *otmp, boolean being_worn)
|
|||||||
if (being_worn && objects[otmp->otyp].oc_oprop == PROTECTION)
|
if (being_worn && objects[otmp->otyp].oc_oprop == PROTECTION)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
arti = get_artifact(otmp);
|
arti = get_artifact(otmp);
|
||||||
if (!arti)
|
if (arti == &nonartifact)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return (boolean) ((arti->cspfx & SPFX_PROTECT) != 0
|
return (boolean) ((arti->cspfx & SPFX_PROTECT) != 0
|
||||||
|| (being_worn && (arti->spfx & SPFX_PROTECT) != 0));
|
|| (being_worn && (arti->spfx & SPFX_PROTECT) != 0));
|
||||||
@@ -629,7 +635,7 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask)
|
|||||||
register uchar dtyp;
|
register uchar dtyp;
|
||||||
register long spfx;
|
register long spfx;
|
||||||
|
|
||||||
if (!oart)
|
if (oart == &nonartifact)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* effects from the defn field */
|
/* effects from the defn field */
|
||||||
@@ -656,7 +662,7 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask)
|
|||||||
for (obj = gi.invent; obj; obj = obj->nobj) {
|
for (obj = gi.invent; obj; obj = obj->nobj) {
|
||||||
if (obj != otmp && obj->oartifact) {
|
if (obj != otmp && obj->oartifact) {
|
||||||
art = get_artifact(obj);
|
art = get_artifact(obj);
|
||||||
if (art && art->cary.adtyp == dtyp) {
|
if (art != &nonartifact && art->cary.adtyp == dtyp) {
|
||||||
mask = (long *) 0;
|
mask = (long *) 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -677,7 +683,7 @@ set_artifact_intrinsic(struct obj *otmp, boolean on, long wp_mask)
|
|||||||
for (obj = gi.invent; obj; obj = obj->nobj)
|
for (obj = gi.invent; obj; obj = obj->nobj)
|
||||||
if (obj != otmp && obj->oartifact) {
|
if (obj != otmp && obj->oartifact) {
|
||||||
art = get_artifact(obj);
|
art = get_artifact(obj);
|
||||||
if (art)
|
if (art != &nonartifact)
|
||||||
spfx &= ~art->cspfx;
|
spfx &= ~art->cspfx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -807,7 +813,7 @@ touch_artifact(struct obj *obj, struct monst *mon)
|
|||||||
boolean badclass, badalign, self_willed, yours;
|
boolean badclass, badalign, self_willed, yours;
|
||||||
|
|
||||||
touch_blasted = FALSE;
|
touch_blasted = FALSE;
|
||||||
if (!oart)
|
if (oart == &nonartifact)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
yours = (mon == &gy.youmonst);
|
yours = (mon == &gy.youmonst);
|
||||||
@@ -876,7 +882,7 @@ arti_immune(struct obj *obj, int dtyp)
|
|||||||
{
|
{
|
||||||
register const struct artifact *weap = get_artifact(obj);
|
register const struct artifact *weap = get_artifact(obj);
|
||||||
|
|
||||||
if (!weap)
|
if (weap == &nonartifact)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (dtyp == AD_PHYS)
|
if (dtyp == AD_PHYS)
|
||||||
return FALSE; /* nothing is immune to phys dmg */
|
return FALSE; /* nothing is immune to phys dmg */
|
||||||
@@ -890,7 +896,7 @@ bane_applies(const struct artifact *oart, struct monst *mon)
|
|||||||
{
|
{
|
||||||
struct artifact atmp;
|
struct artifact atmp;
|
||||||
|
|
||||||
if (oart && (oart->spfx & SPFX_DBONUS) != 0) {
|
if (oart != &nonartifact && (oart->spfx & SPFX_DBONUS) != 0) {
|
||||||
atmp = *oart;
|
atmp = *oart;
|
||||||
atmp.spfx &= SPFX_DBONUS; /* clear other spfx fields */
|
atmp.spfx &= SPFX_DBONUS; /* clear other spfx fields */
|
||||||
if (spec_applies(&atmp, mon))
|
if (spec_applies(&atmp, mon))
|
||||||
@@ -961,7 +967,7 @@ spec_m2(struct obj *otmp)
|
|||||||
{
|
{
|
||||||
const struct artifact *artifact = get_artifact(otmp);
|
const struct artifact *artifact = get_artifact(otmp);
|
||||||
|
|
||||||
if (artifact)
|
if (artifact != &nonartifact)
|
||||||
return artifact->mtype;
|
return artifact->mtype;
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
@@ -975,7 +981,7 @@ spec_abon(struct obj *otmp, struct monst *mon)
|
|||||||
/* no need for an extra check for `NO_ATTK' because this will
|
/* no need for an extra check for `NO_ATTK' because this will
|
||||||
always return 0 for any artifact which has that attribute */
|
always return 0 for any artifact which has that attribute */
|
||||||
|
|
||||||
if (weap && weap->attk.damn && spec_applies(weap, mon))
|
if (weap != &nonartifact && weap->attk.damn && spec_applies(weap, mon))
|
||||||
return rnd((int) weap->attk.damn);
|
return rnd((int) weap->attk.damn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -986,7 +992,8 @@ spec_dbon(struct obj *otmp, struct monst *mon, int tmp)
|
|||||||
{
|
{
|
||||||
register const struct artifact *weap = get_artifact(otmp);
|
register const struct artifact *weap = get_artifact(otmp);
|
||||||
|
|
||||||
if (!weap || (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */
|
if ((weap == &nonartifact)
|
||||||
|
|| (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */
|
||||||
&& weap->attk.damn == 0 && weap->attk.damd == 0))
|
&& weap->attk.damn == 0 && weap->attk.damd == 0))
|
||||||
gs.spec_dbon_applies = FALSE;
|
gs.spec_dbon_applies = FALSE;
|
||||||
else if (is_art(otmp, ART_GRIMTOOTH))
|
else if (is_art(otmp, ART_GRIMTOOTH))
|
||||||
@@ -1660,7 +1667,7 @@ arti_invoke(struct obj *obj)
|
|||||||
impossible("arti_invoke without obj");
|
impossible("arti_invoke without obj");
|
||||||
return ECMD_OK;
|
return ECMD_OK;
|
||||||
}
|
}
|
||||||
if (!oart || !oart->inv_prop) {
|
if (oart == &nonartifact || !oart->inv_prop) {
|
||||||
if (obj->otyp == CRYSTAL_BALL)
|
if (obj->otyp == CRYSTAL_BALL)
|
||||||
use_crystal_ball(&obj);
|
use_crystal_ball(&obj);
|
||||||
else
|
else
|
||||||
@@ -1970,7 +1977,7 @@ finesse_ahriman(struct obj *obj)
|
|||||||
|
|
||||||
/* if we aren't levitating or this isn't an artifact which confers
|
/* if we aren't levitating or this isn't an artifact which confers
|
||||||
levitation via #invoke then freeinv() won't toggle levitation */
|
levitation via #invoke then freeinv() won't toggle levitation */
|
||||||
if (!Levitation || (oart = get_artifact(obj)) == 0
|
if (!Levitation || (oart = get_artifact(obj)) == &nonartifact
|
||||||
|| oart->inv_prop != LEVITATION || !(ELevitation & W_ARTI))
|
|| oart->inv_prop != LEVITATION || !(ELevitation & W_ARTI))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -1998,7 +2005,8 @@ artifact_light(struct obj *obj)
|
|||||||
&& (obj->owornmask & W_ARM) != 0L)
|
&& (obj->owornmask & W_ARM) != 0L)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return (boolean) (get_artifact(obj) && is_art(obj, ART_SUNSWORD));
|
return (boolean) ((get_artifact(obj) != &nonartifact)
|
||||||
|
&& is_art(obj, ART_SUNSWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* KMH -- Talking artifacts are finally implemented */
|
/* KMH -- Talking artifacts are finally implemented */
|
||||||
@@ -2010,7 +2018,7 @@ arti_speak(struct obj *obj)
|
|||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
/* Is this a speaking artifact? */
|
/* Is this a speaking artifact? */
|
||||||
if (!oart || !(oart->spfx & SPFX_SPEAK))
|
if (oart == &nonartifact || !(oart->spfx & SPFX_SPEAK))
|
||||||
return ECMD_OK; /* nothing happened */
|
return ECMD_OK; /* nothing happened */
|
||||||
|
|
||||||
line = getrumor(bcsign(obj), buf, TRUE);
|
line = getrumor(bcsign(obj), buf, TRUE);
|
||||||
@@ -2027,7 +2035,8 @@ artifact_has_invprop(struct obj *otmp, uchar inv_prop)
|
|||||||
{
|
{
|
||||||
const struct artifact *arti = get_artifact(otmp);
|
const struct artifact *arti = get_artifact(otmp);
|
||||||
|
|
||||||
return (boolean) (arti && (arti->inv_prop == inv_prop));
|
return (boolean) ((arti != &nonartifact)
|
||||||
|
&& (arti->inv_prop == inv_prop));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the price sold to the hero of a given artifact or unique item */
|
/* Return the price sold to the hero of a given artifact or unique item */
|
||||||
@@ -2121,7 +2130,7 @@ what_gives(long *abil)
|
|||||||
&& (abil != &EWarn_of_mon || gc.context.warntype.obj)) {
|
&& (abil != &EWarn_of_mon || gc.context.warntype.obj)) {
|
||||||
const struct artifact *art = get_artifact(obj);
|
const struct artifact *art = get_artifact(obj);
|
||||||
|
|
||||||
if (art) {
|
if (art != &nonartifact) {
|
||||||
if (dtyp) {
|
if (dtyp) {
|
||||||
if (art->cary.adtyp == dtyp /* carried */
|
if (art->cary.adtyp == dtyp /* carried */
|
||||||
|| (art->defn.adtyp == dtyp /* defends while worn */
|
|| (art->defn.adtyp == dtyp /* defends while worn */
|
||||||
@@ -2332,7 +2341,7 @@ untouchable(
|
|||||||
|| (obj->otyp == LEASH && obj->leashmon)
|
|| (obj->otyp == LEASH && obj->leashmon)
|
||||||
|| (Is_container(obj) && Has_contents(obj))))));
|
|| (Is_container(obj) && Has_contents(obj))))));
|
||||||
|
|
||||||
if ((art = get_artifact(obj)) != 0) {
|
if ((art = get_artifact(obj)) != &nonartifact) {
|
||||||
carryeffect = (art->cary.adtyp || art->cspfx);
|
carryeffect = (art->cary.adtyp || art->cspfx);
|
||||||
invoked = (art->inv_prop > 0 && art->inv_prop <= LAST_PROP
|
invoked = (art->inv_prop > 0 && art->inv_prop <= LAST_PROP
|
||||||
&& (u.uprops[art->inv_prop].extrinsic & W_ARTI) != 0L);
|
&& (u.uprops[art->inv_prop].extrinsic & W_ARTI) != 0L);
|
||||||
@@ -2524,6 +2533,7 @@ has_magic_key(struct monst *mon) /* if null, hero assumed */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* #define is_art(o,art) ((o) && (o)->oartifact == (art)) */
|
/* #define is_art(o,art) ((o) && (o)->oartifact == (art)) */
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
is_art(struct obj *obj, int art)
|
is_art(struct obj *obj, int art)
|
||||||
{
|
{
|
||||||
@@ -2532,4 +2542,20 @@ is_art(struct obj *obj, int art)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #define get_artifact(o) \
|
||||||
|
(((o) && (o)->oartifact) ? &artilist[(int) (o)->oartifact] \
|
||||||
|
: &nonartifact) */
|
||||||
|
|
||||||
|
static struct artifact *
|
||||||
|
get_artifact(struct obj *obj)
|
||||||
|
{
|
||||||
|
if (obj) {
|
||||||
|
int artidx = (int) obj->oartifact;
|
||||||
|
|
||||||
|
/* skip 0, 1st artifact at 1 */
|
||||||
|
if (artidx > 0 && artidx < SIZE(artilist))
|
||||||
|
return &artilist[artidx];
|
||||||
|
}
|
||||||
|
return &nonartifact;
|
||||||
|
}
|
||||||
/*artifact.c*/
|
/*artifact.c*/
|
||||||
|
|||||||
Reference in New Issue
Block a user