/* * Implementation of weapons. Mostly stubbed out at present. */ #include #include "obj.h" #include "vars.h" #include "dice.h" #include "pline.h" #include "format.h" #include "structs.h" #include "objtypes.h" typedef struct weapon WEAPON; /* * Private data for a weapon. Just plusses and a known flag. */ struct weapon { unsigned int flags; #define WF_KNOWN 0x00000001 int bonus; } ; /* * Return the WEAPON * for an OBJ *. */ static WEAPON *weapon_for_obj(OBJ *o) { if (objtypes[o->type].class != OC_WEAPON) panic("non-weapon where weapon needed"); return(o->private); } /* * The new method for weapons. */ static OBJ *new_weapon(int type __attribute__((__unused__)), OBJ *o) { WEAPON *w; w = malloc(sizeof(WEAPON)); w->flags = 0; w->bonus = 0; o->private = w; return(o); } /* * The old method for weapnos. */ static void old_weapon(OBJ *o) { free(o->private); } /* * Weapon-specific format conditionals. */ static int fmt_cond_weapon(char ch, INVOBJ *io) { switch (ch) { case 'K': return(weapon_for_obj(io->v[0])->flags&WF_KNOWN); break; } panic("invalid conditional +%c for weapon",ch); } /* * Weapon-specific formats. */ static void fmt_spec_weapon(FILE *f, char ch, INVOBJ *io) { switch (ch) { case 'P': fprintf(f,"%+d",weapon_for_obj(io->v[0])->bonus); break; default: panic("invalid format %%+%c for weapon",ch); break; } } /* * The collapsible method for weapons. * * Weapons are collapsible if they look the same, which means, if they * are the same type and either (a) neither one has its plusses known * or (b) their plusses are identical. */ static int collapsible_weapon(OBJ *o1, OBJ *o2) { WEAPON *w1; WEAPON *w2; int t1; int t2; w1 = o1->private; w2 = o2->private; t1 = o1->type; t2 = o2->type; #if 0 if ((t1 == OBJ_ARROW_OF_DEATH) && !(w1->flags & WF_KNOWN)) t1 = OBJ_ARROW; if ((t2 == OBJ_ARROW_OF_DEATH) && !(w2->flags & WF_KNOWN)) t2 = OBJ_ARROW; #endif if (t1 != t2) return(0); if (w1->flags != w2->flags) return(0); if ((w1->flags & WF_KNOWN) && (w1->bonus != w2->bonus)) return(0); return(1); } /* * The identical method for weapons. */ static int identical_weapon(OBJ *o1, OBJ *o2) { WEAPON *w1; WEAPON *w2; if (o1->type != o2->type) return(0); w1 = o1->private; w2 = o2->private; if ((w1->flags != w2->flags) || (w1->bonus != w2->bonus)) return(0); return(1); } /* * The identified method for weapons. */ static int identified_weapon(INVOBJ *io) { return(weapon_for_obj(io->v[0])->flags & WF_KNOWN); } /* * The identify method for weapons. If the object is singular, just * identify it. Otherwise, pick a representative, split it off into * its own INVOBJ, and identify it. */ static INVOBJ *identify_weapon(INVOBJ *io) { int i; int r; OBJ *o; if (io->n == 1) { weapon_for_obj(io->v[0])->flags |= WF_KNOWN; return(io); } r = rnd(io->dispn); for (i=0;in;i++) { r -= io->v[i]->number; if (r < 0) break; } if (i >= io->n) panic("invobj overrun in weapon identify"); o = remove_obj_from_invobj(i,io); weapon_for_obj(o)->flags |= WF_KNOWN; return(add_obj_to_inv(o,io->inv)); } /* * The OBJOPS vector for weapons. */ #define format_weapon std_format #define split_weapon std_split #define moved_weapon noop_moved OBJOPS objops_weapon = OBJOPS_INIT(weapon);