mirror of
https://github.com/vattam/BSDGames.git
synced 2025-12-21 03:14:50 +00:00
Initial revision
git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5198 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
466
hack/hack.potion.c
Normal file
466
hack/hack.potion.c
Normal file
@@ -0,0 +1,466 @@
|
||||
/* $NetBSD: hack.potion.c,v 1.5 2001/03/25 20:44:02 jsm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
|
||||
* Amsterdam
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of the Stichting Centrum voor Wiskunde en
|
||||
* Informatica, nor the names of its contributors may be used to endorse or
|
||||
* promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: hack.potion.c,v 1.5 2001/03/25 20:44:02 jsm Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "hack.h"
|
||||
#include "extern.h"
|
||||
|
||||
int
|
||||
dodrink()
|
||||
{
|
||||
struct obj *otmp, *objs;
|
||||
struct monst *mtmp;
|
||||
int unkn = 0, nothing = 0;
|
||||
|
||||
otmp = getobj("!", "drink");
|
||||
if (!otmp)
|
||||
return (0);
|
||||
if (!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
|
||||
ghost_from_bottle();
|
||||
goto use_it;
|
||||
}
|
||||
switch (otmp->otyp) {
|
||||
case POT_RESTORE_STRENGTH:
|
||||
unkn++;
|
||||
pline("Wow! This makes you feel great!");
|
||||
if (u.ustr < u.ustrmax) {
|
||||
u.ustr = u.ustrmax;
|
||||
flags.botl = 1;
|
||||
}
|
||||
break;
|
||||
case POT_BOOZE:
|
||||
unkn++;
|
||||
pline("Ooph! This tastes like liquid fire!");
|
||||
Confusion += d(3, 8);
|
||||
/* the whiskey makes us feel better */
|
||||
if (u.uhp < u.uhpmax)
|
||||
losehp(-1, "bottle of whiskey");
|
||||
if (!rn2(4)) {
|
||||
pline("You pass out.");
|
||||
multi = -rnd(15);
|
||||
nomovemsg = "You awake with a headache.";
|
||||
}
|
||||
break;
|
||||
case POT_INVISIBILITY:
|
||||
if (Invis || See_invisible)
|
||||
nothing++;
|
||||
else {
|
||||
if (!Blind)
|
||||
pline("Gee! All of a sudden, you can't see yourself.");
|
||||
else
|
||||
pline("You feel rather airy."), unkn++;
|
||||
newsym(u.ux, u.uy);
|
||||
}
|
||||
Invis += rn1(15, 31);
|
||||
break;
|
||||
case POT_FRUIT_JUICE:
|
||||
pline("This tastes like fruit juice.");
|
||||
lesshungry(20);
|
||||
break;
|
||||
case POT_HEALING:
|
||||
pline("You begin to feel better.");
|
||||
flags.botl = 1;
|
||||
u.uhp += rnd(10);
|
||||
if (u.uhp > u.uhpmax)
|
||||
u.uhp = ++u.uhpmax;
|
||||
if (Blind)
|
||||
Blind = 1; /* see on next move */
|
||||
if (Sick)
|
||||
Sick = 0;
|
||||
break;
|
||||
case POT_PARALYSIS:
|
||||
if (Levitation)
|
||||
pline("You are motionlessly suspended.");
|
||||
else
|
||||
pline("Your feet are frozen to the floor!");
|
||||
nomul(-(rn1(10, 25)));
|
||||
break;
|
||||
case POT_MONSTER_DETECTION:
|
||||
if (!fmon) {
|
||||
strange_feeling(otmp, "You feel threatened.");
|
||||
return (1);
|
||||
} else {
|
||||
cls();
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
||||
if (mtmp->mx > 0)
|
||||
at(mtmp->mx, mtmp->my, mtmp->data->mlet);
|
||||
prme();
|
||||
pline("You sense the presence of monsters.");
|
||||
more();
|
||||
docrt();
|
||||
}
|
||||
break;
|
||||
case POT_OBJECT_DETECTION:
|
||||
if (!fobj) {
|
||||
strange_feeling(otmp, "You feel a pull downward.");
|
||||
return (1);
|
||||
} else {
|
||||
for (objs = fobj; objs; objs = objs->nobj)
|
||||
if (objs->ox != u.ux || objs->oy != u.uy)
|
||||
goto outobjmap;
|
||||
pline("You sense the presence of objects close nearby.");
|
||||
break;
|
||||
outobjmap:
|
||||
cls();
|
||||
for (objs = fobj; objs; objs = objs->nobj)
|
||||
at(objs->ox, objs->oy, objs->olet);
|
||||
prme();
|
||||
pline("You sense the presence of objects.");
|
||||
more();
|
||||
docrt();
|
||||
}
|
||||
break;
|
||||
case POT_SICKNESS:
|
||||
pline("Yech! This stuff tastes like poison.");
|
||||
if (Poison_resistance)
|
||||
pline("(But in fact it was biologically contaminated orange juice.)");
|
||||
losestr(rn1(4, 3));
|
||||
losehp(rnd(10), "contaminated potion");
|
||||
break;
|
||||
case POT_CONFUSION:
|
||||
if (!Confusion)
|
||||
pline("Huh, What? Where am I?");
|
||||
else
|
||||
nothing++;
|
||||
Confusion += rn1(7, 16);
|
||||
break;
|
||||
case POT_GAIN_STRENGTH:
|
||||
pline("Wow do you feel strong!");
|
||||
if (u.ustr >= 118)
|
||||
break; /* > 118 is impossible */
|
||||
if (u.ustr > 17)
|
||||
u.ustr += rnd(118 - u.ustr);
|
||||
else
|
||||
u.ustr++;
|
||||
if (u.ustr > u.ustrmax)
|
||||
u.ustrmax = u.ustr;
|
||||
flags.botl = 1;
|
||||
break;
|
||||
case POT_SPEED:
|
||||
if (Wounded_legs) {
|
||||
heal_legs();
|
||||
unkn++;
|
||||
break;
|
||||
}
|
||||
if (!(Fast & ~INTRINSIC))
|
||||
pline("You are suddenly moving much faster.");
|
||||
else
|
||||
pline("Your legs get new energy."), unkn++;
|
||||
Fast += rn1(10, 100);
|
||||
break;
|
||||
case POT_BLINDNESS:
|
||||
if (!Blind)
|
||||
pline("A cloud of darkness falls upon you.");
|
||||
else
|
||||
nothing++;
|
||||
Blind += rn1(100, 250);
|
||||
seeoff(0);
|
||||
break;
|
||||
case POT_GAIN_LEVEL:
|
||||
pluslvl();
|
||||
break;
|
||||
case POT_EXTRA_HEALING:
|
||||
pline("You feel much better.");
|
||||
flags.botl = 1;
|
||||
u.uhp += d(2, 20) + 1;
|
||||
if (u.uhp > u.uhpmax)
|
||||
u.uhp = (u.uhpmax += 2);
|
||||
if (Blind)
|
||||
Blind = 1;
|
||||
if (Sick)
|
||||
Sick = 0;
|
||||
break;
|
||||
case POT_LEVITATION:
|
||||
if (!Levitation)
|
||||
float_up();
|
||||
else
|
||||
nothing++;
|
||||
Levitation += rnd(100);
|
||||
u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
|
||||
break;
|
||||
default:
|
||||
impossible("What a funny potion! (%u)", otmp->otyp);
|
||||
return (0);
|
||||
}
|
||||
if (nothing) {
|
||||
unkn++;
|
||||
pline("You have a peculiar feeling for a moment, then it passes.");
|
||||
}
|
||||
if (otmp->dknown && !objects[otmp->otyp].oc_name_known) {
|
||||
if (!unkn) {
|
||||
objects[otmp->otyp].oc_name_known = 1;
|
||||
more_experienced(0, 10);
|
||||
} else if (!objects[otmp->otyp].oc_uname)
|
||||
docall(otmp);
|
||||
}
|
||||
use_it:
|
||||
useup(otmp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
pluslvl()
|
||||
{
|
||||
int num;
|
||||
|
||||
pline("You feel more experienced.");
|
||||
num = rnd(10);
|
||||
u.uhpmax += num;
|
||||
u.uhp += num;
|
||||
if (u.ulevel < 14) {
|
||||
u.uexp = newuexp() + 1;
|
||||
pline("Welcome to experience level %u.", ++u.ulevel);
|
||||
}
|
||||
flags.botl = 1;
|
||||
}
|
||||
|
||||
void
|
||||
strange_feeling(obj, txt)
|
||||
struct obj *obj;
|
||||
const char *txt;
|
||||
{
|
||||
if (flags.beginner)
|
||||
pline("You have a strange feeling for a moment, then it passes.");
|
||||
else
|
||||
pline(txt);
|
||||
if (!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
|
||||
docall(obj);
|
||||
useup(obj);
|
||||
}
|
||||
|
||||
const char *const bottlenames[] = {
|
||||
"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
|
||||
};
|
||||
|
||||
void
|
||||
potionhit(mon, obj)
|
||||
struct monst *mon;
|
||||
struct obj *obj;
|
||||
{
|
||||
const char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
|
||||
boolean uclose, isyou = (mon == &youmonst);
|
||||
|
||||
if (isyou) {
|
||||
uclose = TRUE;
|
||||
pline("The %s crashes on your head and breaks into shivers.",
|
||||
botlnam);
|
||||
losehp(rnd(2), "thrown potion");
|
||||
} else {
|
||||
uclose = (dist(mon->mx, mon->my) < 3);
|
||||
/* perhaps 'E' and 'a' have no head? */
|
||||
pline("The %s crashes on %s's head and breaks into shivers.",
|
||||
botlnam, monnam(mon));
|
||||
if (rn2(5) && mon->mhp > 1)
|
||||
mon->mhp--;
|
||||
}
|
||||
pline("The %s evaporates.", xname(obj));
|
||||
|
||||
if (!isyou && !rn2(3))
|
||||
switch (obj->otyp) {
|
||||
|
||||
case POT_RESTORE_STRENGTH:
|
||||
case POT_GAIN_STRENGTH:
|
||||
case POT_HEALING:
|
||||
case POT_EXTRA_HEALING:
|
||||
if (mon->mhp < mon->mhpmax) {
|
||||
mon->mhp = mon->mhpmax;
|
||||
pline("%s looks sound and hale again!", Monnam(mon));
|
||||
}
|
||||
break;
|
||||
case POT_SICKNESS:
|
||||
if (mon->mhpmax > 3)
|
||||
mon->mhpmax /= 2;
|
||||
if (mon->mhp > 2)
|
||||
mon->mhp /= 2;
|
||||
break;
|
||||
case POT_CONFUSION:
|
||||
case POT_BOOZE:
|
||||
mon->mconf = 1;
|
||||
break;
|
||||
case POT_INVISIBILITY:
|
||||
unpmon(mon);
|
||||
mon->minvis = 1;
|
||||
pmon(mon);
|
||||
break;
|
||||
case POT_PARALYSIS:
|
||||
mon->mfroz = 1;
|
||||
break;
|
||||
case POT_SPEED:
|
||||
mon->mspeed = MFAST;
|
||||
break;
|
||||
case POT_BLINDNESS:
|
||||
mon->mblinded |= 64 + rn2(64);
|
||||
break;
|
||||
/*
|
||||
* case POT_GAIN_LEVEL: case POT_LEVITATION: case
|
||||
* POT_FRUIT_JUICE: case POT_MONSTER_DETECTION: case
|
||||
* POT_OBJECT_DETECTION: break;
|
||||
*/
|
||||
}
|
||||
if (uclose && rn2(5))
|
||||
potionbreathe(obj);
|
||||
obfree(obj, Null(obj));
|
||||
}
|
||||
|
||||
void
|
||||
potionbreathe(obj)
|
||||
struct obj *obj;
|
||||
{
|
||||
switch (obj->otyp) {
|
||||
case POT_RESTORE_STRENGTH:
|
||||
case POT_GAIN_STRENGTH:
|
||||
if (u.ustr < u.ustrmax)
|
||||
u.ustr++, flags.botl = 1;
|
||||
break;
|
||||
case POT_HEALING:
|
||||
case POT_EXTRA_HEALING:
|
||||
if (u.uhp < u.uhpmax)
|
||||
u.uhp++, flags.botl = 1;
|
||||
break;
|
||||
case POT_SICKNESS:
|
||||
if (u.uhp <= 5)
|
||||
u.uhp = 1;
|
||||
else
|
||||
u.uhp -= 5;
|
||||
flags.botl = 1;
|
||||
break;
|
||||
case POT_CONFUSION:
|
||||
case POT_BOOZE:
|
||||
if (!Confusion)
|
||||
pline("You feel somewhat dizzy.");
|
||||
Confusion += rnd(5);
|
||||
break;
|
||||
case POT_INVISIBILITY:
|
||||
pline("For an instant you couldn't see your right hand.");
|
||||
break;
|
||||
case POT_PARALYSIS:
|
||||
pline("Something seems to be holding you.");
|
||||
nomul(-rnd(5));
|
||||
break;
|
||||
case POT_SPEED:
|
||||
Fast += rnd(5);
|
||||
pline("Your knees seem more flexible now.");
|
||||
break;
|
||||
case POT_BLINDNESS:
|
||||
if (!Blind)
|
||||
pline("It suddenly gets dark.");
|
||||
Blind += rnd(5);
|
||||
seeoff(0);
|
||||
break;
|
||||
/*
|
||||
* case POT_GAIN_LEVEL: case POT_LEVITATION: case
|
||||
* POT_FRUIT_JUICE: case POT_MONSTER_DETECTION: case
|
||||
* POT_OBJECT_DETECTION: break;
|
||||
*/
|
||||
}
|
||||
/* note: no obfree() */
|
||||
}
|
||||
|
||||
/*
|
||||
* -- rudimentary -- to do this correctly requires much more work
|
||||
* -- all sharp weapons get one or more qualities derived from the potions
|
||||
* -- texts on scrolls may be (partially) wiped out; do they become blank?
|
||||
* -- or does their effect change, like under Confusion?
|
||||
* -- all objects may be made invisible by POT_INVISIBILITY
|
||||
* -- If the flask is small, can one dip a large object? Does it magically
|
||||
* -- become a jug? Etc.
|
||||
*/
|
||||
int
|
||||
dodip()
|
||||
{
|
||||
struct obj *potion, *obj;
|
||||
|
||||
if (!(obj = getobj("#", "dip")))
|
||||
return (0);
|
||||
if (!(potion = getobj("!", "dip into")))
|
||||
return (0);
|
||||
pline("Interesting...");
|
||||
if (obj->otyp == ARROW || obj->otyp == DART ||
|
||||
obj->otyp == CROSSBOW_BOLT) {
|
||||
if (potion->otyp == POT_SICKNESS) {
|
||||
useup(potion);
|
||||
if (obj->spe < 7)
|
||||
obj->spe++; /* %% */
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
ghost_from_bottle()
|
||||
{
|
||||
struct monst *mtmp;
|
||||
|
||||
if (!(mtmp = makemon(PM_GHOST, u.ux, u.uy))) {
|
||||
pline("This bottle turns out to be empty.");
|
||||
return;
|
||||
}
|
||||
mnexto(mtmp);
|
||||
pline("As you open the bottle, an enormous ghost emerges!");
|
||||
pline("You are frightened to death, and unable to move.");
|
||||
nomul(-3);
|
||||
}
|
||||
Reference in New Issue
Block a user