/* * Implementation of wands. */ #include #include "obj.h" #include "vars.h" #include "util.h" #include "pline.h" #include "format.h" #include "structs.h" #include "objtypes.h" #include "obj-wand.h" typedef struct wand WAND; /* * Private data for wands. All we have here are the charge count and a * flag describing whether the player knows the charge count. */ struct wand { unsigned int flags; #define WF_KNOWN 0x00000001 int charges; } ; /* * Return the WAND * for an OBJ *. */ static WAND *wand_for_obj(OBJ *o) { if (objtypes[o->type].class != OC_WAND) panic("non-wand where wand needed"); return(o->private); } /* * Zap something. It is the caller's responsibility to ensure the * argument INVOBJ is exactly one wand. */ void zap_it(INVOBJ *io) { OBJ *o; WAND *w; if (io->n > 1) abort(); o = io->v[0]; w = wand_for_obj(o); if (w->charges < 1) { pline("Nothing happens."); return; } w->charges --; switch (o->type) { case OBJ_WAND_OF_LIGHT: objtypes[o->type].flags |= OTF_KNOWN; break; } } /* * The new method for wands. They are all born with zero charges; the * charge count must be set elsewhere. */ static OBJ *new_wand(int type __attribute__((__unused__)), OBJ *o) { WAND *w; w = malloc(sizeof(WAND)); w->flags = 0; w->charges = 0; o->private = w; return(o); } /* * The old method for wands. */ static void old_wand(OBJ *o) { free(o->private); } /* * The identified method for wands. */ static int identified_wand(INVOBJ *io) { return( (objtypes[io->v[0]->type].flags & OTF_KNOWN) && (wand_for_obj(io->v[0])->flags & WF_KNOWN) ); } /* * The identify method for wands. */ static INVOBJ *identify_wand(INVOBJ *io) { objtypes[io->v[0]->type].flags |= OTF_KNOWN; wand_for_obj(io->v[0])->flags |= WF_KNOWN; return(io); } /* * The OBJOPS for wands. */ #define format_wand std_format #define fmt_cond_wand panic_fmt_cond #define fmt_spec_wand panic_fmt_spec #define collapsible_wand never_collapsible #define identical_wand never_identical #define split_wand std_split #define moved_wand noop_moved OBJOPS objops_wand = OBJOPS_INIT(wand);