/* * Implementation of potions. */ #include #include "mon.h" #include "obj.h" #include "vars.h" #include "dice.h" #include "pline.h" #include "fuses.h" #include "effect.h" #include "format.h" #include "structs.h" #include "objtypes.h" #include "mon-@-you.h" #include "obj-potion.h" typedef struct potioneffect POTIONEFFECT; /* * A potion effect private data. */ struct potioneffect { MONST *m; EFFECT *eff; int potion; TIME expires; int expfuse; const char *endmsg; } ; /* * Apply a potion effect. */ static void apply_potion(MONST *m, void *ev) { POTIONEFFECT *e; e = ev; switch (e->potion) { // case OBJ_POTION_OF_CLAIRVOYANCE: // case OBJ_POTION_OF_CONFUSION: // case OBJ_POTION_OF_FIRE_RESISTANCE: // case OBJ_POTION_OF_GIANT_STRENGTH: // case OBJ_POTION_OF_HEROISM: // case OBJ_POTION_OF_INFRAVISION: // case OBJ_POTION_OF_INVISIBILITY: // case OBJ_POTION_OF_LEVITATION: // case OBJ_POTION_OF_MEMORY: // case OBJ_POTION_OF_PERCEPTION: case OBJ_POTION_OF_SEE_INVISIBLE: m->flags |= MF_SEE_INVISIBLE; break; // case OBJ_POTION_OF_SLEEP: case OBJ_POTION_OF_SPEED: m->speed /= 2; break; // case OBJ_POTION_OF_WATER_BREATHING: } } /* * Tear a potion effect down prematurely. */ static void death_potion(MONST *m __attribute__((__unused__)), void *ev) { cancelfuse(((POTIONEFFECT *)ev)->expfuse); free(ev); } static EFFECTOPS effops_potion = EFFECTOPS_INIT(potion); /* * Expire a potion effect. */ static void potion_expire(long int liarg __attribute__((__unused__)), void *ev) { POTIONEFFECT *e; e = ev; if ((e->m == you) && e->endmsg) pline("%s",e->endmsg); effect_remove(e->m,e->eff); free(e); } /* * Add a timed potion effect. */ static void add_potion_effect(MONST *m, int ticks, int potion, const char *endmsg) { POTIONEFFECT *e; e = malloc(sizeof(POTIONEFFECT)); e->m = m; e->eff = effect_add(m,e,&effops_potion); e->potion = potion; e->expires = curtime + (ticks * TIMESCALE); e->expfuse = addfuse_abs(&potion_expire,0,e,e->expires); e->endmsg = endmsg; } /* * Quaff a potion. This is also responsible for destroying the potion, * when appropriate. */ void quaff_it(INVOBJ *io) { OBJ *o; if (io->n > 1) abort(); o = io->v[0]; if (objtypes[o->type].class != OC_POTION) { pline("Quaffing non-potion?"); impossible(); return; } switch (o->type) { // case OBJ_POTION_OF_AMNESIA: // case OBJ_POTION_OF_CLAIRVOYANCE: // case OBJ_POTION_OF_CONFUSION: // case OBJ_POTION_OF_FIRE_RESISTANCE: // case OBJ_POTION_OF_GAIN_STRENGTH: // case OBJ_POTION_OF_GIANT_STRENGTH: case OBJ_POTION_OF_HEALING: objtypes[OBJ_POTION_OF_HEALING].flags |= OTF_KNOWN; pline("You feel better!"); gainhp(you,roll("10000+d5000")); break; // case OBJ_POTION_OF_HEROISM: // case OBJ_POTION_OF_INFRAVISION: // case OBJ_POTION_OF_INVISIBILITY: // case OBJ_POTION_OF_LEVITATION: // case OBJ_POTION_OF_MEMORY: // case OBJ_POTION_OF_PERCEPTION: // case OBJ_POTION_OF_RESTORATION: case OBJ_POTION_OF_SEE_INVISIBLE: objtypes[OBJ_POTION_OF_SEE_INVISIBLE].flags |= OTF_KNOWN; pline("Your vision seems exceptionally sharp!"); add_potion_effect(you,roll("150+d100"),OBJ_POTION_OF_SEE_INVISIBLE,"Your vision returns to normal."); break; // case OBJ_POTION_OF_SLEEP: case OBJ_POTION_OF_SPEED: pline("You seem to be moving faster!"); add_potion_effect(you,roll("20+d10"),OBJ_POTION_OF_SPEED,"You seem to be slowing down."); break; // case OBJ_POTION_OF_WATER_BREATHING: } inv_remove(io->inv,io); invobjfree(io); } /* * The identical method for potions. */ static int identical_potion(OBJ *o1, OBJ *o2) { return(o1->type==o2->type); } /* * The collapsible method for potions. */ static int collapsible_potion(OBJ *o1, OBJ *o2) { return(identical_potion(o1,o2)); } /* * The identified method for potions. */ static int identified_potion(INVOBJ *io) { return(!!(objtypes[io->v[0]->type].flags&OTF_KNOWN)); } /* * The identify method for potions. */ static INVOBJ *identify_potion(INVOBJ *io) { objtypes[io->v[0]->type].flags |= OTF_KNOWN; return(io); } /* * The OBJOPS vector for potions. */ #define new_potion noop_new #define old_potion noop_old #define format_potion std_format #define fmt_cond_potion panic_fmt_cond #define fmt_spec_potion panic_fmt_spec #define split_potion std_split #define moved_potion noop_moved OBJOPS objops_potion = OBJOPS_INIT(potion);