2142 lines
38 KiB
C
2142 lines
38 KiB
C
/* program VERB.C */
|
|
|
|
#include "stdio.h"
|
|
#include "advent.h"
|
|
#include "advdec.h"
|
|
|
|
/* Initialize default verb messages */
|
|
static _CONST int actmsg[56] = {
|
|
0, 24, 29, 0, 33, 0, 33, 38, 38, 42,
|
|
14, 43, 110, 29, 110, 73, 75, 29, 13, 59,
|
|
59, 174, 313, 67, 13, 147, 155, 369, 146, 110,
|
|
13, 13, 24, 25, 110, 262, 14, 29, 271, 14,
|
|
14, 24, 29, 38, 24, 331, 24, 109, 332, 0,
|
|
0, 348, 358, 0, 364, 0};
|
|
|
|
_PROTOTYPE(static int ck_obj, (void));
|
|
_PROTOTYPE(void von, (void));
|
|
_PROTOTYPE(void voff, (void));
|
|
_PROTOTYPE(void vwave, (void));
|
|
_PROTOTYPE(void veat, (void));
|
|
_PROTOTYPE(void vthrow, (void));
|
|
_PROTOTYPE(void vfind, (void));
|
|
_PROTOTYPE(void vfill, (void));
|
|
_PROTOTYPE(void vfeed, (void));
|
|
_PROTOTYPE(void vbreak, (void));
|
|
_PROTOTYPE(void vwake, (void));
|
|
_PROTOTYPE(void vdrop, (void));
|
|
_PROTOTYPE(void vpour, (void));
|
|
_PROTOTYPE(void vput, (void));
|
|
_PROTOTYPE(void vread, (void));
|
|
_PROTOTYPE(void vinsert, (void));
|
|
_PROTOTYPE(void vextract, (void));
|
|
_PROTOTYPE(static boolean do_battle, (int *));
|
|
_PROTOTYPE(void vhit, (void));
|
|
_PROTOTYPE(void vanswer, (void));
|
|
_PROTOTYPE(void vblow, (void));
|
|
_PROTOTYPE(void vdial, (void));
|
|
_PROTOTYPE(void vplay, (void));
|
|
_PROTOTYPE(void vpick, (void));
|
|
_PROTOTYPE(void vput, (void));
|
|
_PROTOTYPE(void vturn, (void));
|
|
_PROTOTYPE(void vget, (void));
|
|
_PROTOTYPE(void vlook, (void));
|
|
|
|
|
|
/*
|
|
Routine to process a transitive verb
|
|
*/
|
|
void trverb()
|
|
{
|
|
newtravel = FALSE;
|
|
switch (verb) {
|
|
case NOTHING:
|
|
case CALM:
|
|
case WALK:
|
|
case QUIT:
|
|
case SCORE:
|
|
case FOO:
|
|
case SUSPEND: break;
|
|
case TAKE: vtake(); break;
|
|
case DROP: vdrop(); break;
|
|
case SAY: bug(34); break;
|
|
case OPEN: vopen(); break;
|
|
case CLOSE: vclose(); break;
|
|
case LOCK: vlock(); break;
|
|
case UNLOCK: vunlock(); break;
|
|
case ON: von(); break;
|
|
case OFF: voff(); break;
|
|
case WAVE: vwave(); break;
|
|
case KILL: vkill(); break;
|
|
case POUR: vpour(); break;
|
|
case EAT: veat(); break;
|
|
case DRINK: vdrink(); break;
|
|
case RUB:
|
|
if (object != LAMP)
|
|
rspeak(76);
|
|
else
|
|
actspk(RUB);
|
|
break;
|
|
case THROW:
|
|
if (prep == PREPDN)
|
|
vput();
|
|
else
|
|
vthrow();
|
|
break;
|
|
case FEED: vfeed(); break;
|
|
case FIND:
|
|
case INVENTORY: vfind(); break;
|
|
case FILL: vfill(); break;
|
|
case BLAST: ivblast(); break;
|
|
case READ: vread(); break;
|
|
case BREAK: vbreak(); break;
|
|
case WAKE: vwake(); break;
|
|
case REMOVE: vextract(); break;
|
|
case YANK: vyank(); break;
|
|
case WEAR: vwear(); break;
|
|
case HIT: vhit(); break;
|
|
case ANSWER: vanswer(); break;
|
|
case BLOW: vblow(); break;
|
|
case DIAL: vdial(); break;
|
|
case PLAY: vplay(); break;
|
|
case PICK: vpick(); break;
|
|
case PUT: vput(); break;
|
|
case TURN: vturn(); break;
|
|
case GET: vget(); break;
|
|
case INSRT: vinsert(); break;
|
|
case LOOK: vlook(); break;
|
|
default:
|
|
printf("This verb is not implemented yet.\n");
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Routine to speak default verb message
|
|
*/
|
|
void actspk(verb)
|
|
int verb;
|
|
{
|
|
int i;
|
|
|
|
if (verb < 1 || verb > 55)
|
|
bug(39);
|
|
i = actmsg[verb];
|
|
if (i)
|
|
rspeak(i);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
CARRY TAKE etc.
|
|
*/
|
|
void vtake()
|
|
{
|
|
int msg;
|
|
|
|
msg = 0;
|
|
if (object == BIRD && !g.closed && athand(BIRD)
|
|
&& g.place[BIRD] != g.loc) {
|
|
rspeak(407);
|
|
return;
|
|
}
|
|
if (prep == PREPOF) {
|
|
if (object && iobj) {
|
|
rspeak(confuz());
|
|
return;
|
|
} else if (!object) {
|
|
object = iobj;
|
|
iobj = 0;
|
|
vdrop();
|
|
return;
|
|
}
|
|
}
|
|
msg = 24;
|
|
if (object == BOAT)
|
|
msg = 281;
|
|
if (plural(object))
|
|
msg = 297;
|
|
if (holding(object)) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
/* Special case objects and fixed objects */
|
|
msg = ck_obj();
|
|
if (g.fixed[object]) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (prep == PREPIN) {
|
|
vinsert();
|
|
return;
|
|
}
|
|
/* Special case for liquids */
|
|
if (object == WATER || object == OIL || object == WINE) {
|
|
if (here(BOTTLE) && here(CASK)) {
|
|
rspeak(315);
|
|
return;
|
|
}
|
|
iobj = object;
|
|
if (here(BOTTLE)) {
|
|
object = BOTTLE;
|
|
if (holding(BOTTLE))
|
|
vfill();
|
|
else
|
|
rspeak(312);
|
|
return;
|
|
} else if (here(CASK)) {
|
|
object = CASK;
|
|
if (holding(CASK))
|
|
vfill();
|
|
else
|
|
rspeak(312);
|
|
return;
|
|
} else {
|
|
rspeak(312);
|
|
return;
|
|
}
|
|
}
|
|
if (object != BEAR && ((burden(0) + burden(object)) > 15)) {
|
|
if (wearng(object)) {
|
|
g.prop[object] = 0;
|
|
bitoff(object, WEARBT);
|
|
}
|
|
rspeak(92);
|
|
return;
|
|
}
|
|
if (prep == PREPFR || enclosed(object)) {
|
|
vextract();
|
|
return;
|
|
}
|
|
msg = 343;
|
|
/* Poster: hides wall safe */
|
|
if (object == POSTER && g.place[SAFE] == 0) {
|
|
g.prop[POSTER] = 1;
|
|
msg = 362;
|
|
/* Move safe and wall containing safe into view */
|
|
drop(SAFE, g.loc);
|
|
drop(WALL2, g.loc);
|
|
}
|
|
/* Boat: need the pole to push it */
|
|
if (object == BOAT) {
|
|
if (!toting(POLE) && g.place[POLE] != -BOAT) {
|
|
rspeak(218);
|
|
return;
|
|
} else {
|
|
g.prop[BOAT] = 1;
|
|
msg = 221;
|
|
}
|
|
}
|
|
/* Special case for bird. */
|
|
if (object == BIRD && g.prop[BIRD] <= 0) {
|
|
if (athand(ROD)) {
|
|
rspeak(26);
|
|
return;
|
|
}
|
|
if (!holding(CAGE)) {
|
|
rspeak(27);
|
|
return;
|
|
}
|
|
if (!ajar(CAGE)) {
|
|
rspeak(358);
|
|
return;
|
|
}
|
|
insert(BIRD, CAGE);
|
|
bitoff(CAGE, OPENBT);
|
|
pspeak(object, -1);
|
|
rspeak(54);
|
|
return;
|
|
}
|
|
/* SWORD If in anvil, need crown & must yank */
|
|
if (object == SWORD && g.prop[SWORD] != 0) {
|
|
if (iobj && iobj != ANVIL) {
|
|
rspeak(noway());
|
|
return;
|
|
}
|
|
if (verb != YANK)
|
|
if (!yes(215, 0, 54))
|
|
return;
|
|
|
|
if (!wearng(CROWN)) {
|
|
g.fixed[SWORD] = -1;
|
|
g.prop[SWORD] = 3;
|
|
pspeak(SWORD, 2);
|
|
return;
|
|
}
|
|
}
|
|
carry(object, g.loc);
|
|
if (object == POLE || object == SKEY || object == SWORD
|
|
|| ((object == CLOAK || object == RING) && !wearng(object)) )
|
|
g.prop[object] = 0;
|
|
|
|
if (verb == YANK || object == SWORD)
|
|
msg = 204;
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
static int ck_obj()
|
|
{
|
|
int msg;
|
|
|
|
msg = noway();
|
|
if (object == PLANT && g.prop[PLANT] <= 0)
|
|
msg = 115;
|
|
if (object == BEAR && g.prop[BEAR] == 1)
|
|
msg = 169;
|
|
if (object == CHAIN && g.prop[BEAR] != 0)
|
|
msg = 170;
|
|
if (object == SWORD && g.prop[SWORD] == 5)
|
|
msg = 208;
|
|
if (object == CLOAK && g.prop[CLOAK] == 2)
|
|
msg = 242;
|
|
if (object == AXE && g.prop[AXE] == 2)
|
|
msg = 246;
|
|
if (object == PHONE)
|
|
msg = 251;
|
|
if (object == BEES || object == HIVE)
|
|
msg = 295;
|
|
if (object == STICKS)
|
|
msg = 296;
|
|
return (msg);
|
|
}
|
|
|
|
/*
|
|
DROP etc.
|
|
*/
|
|
void vdrop()
|
|
{
|
|
int msg;
|
|
|
|
/* Check for dynamite */
|
|
if (holding(ROD2) && object == ROD && !holding(ROD))
|
|
object = ROD2;
|
|
if (plural(object))
|
|
msg = 105;
|
|
else
|
|
msg = 29;
|
|
|
|
if (object == liq(BOTTLE))
|
|
object = BOTTLE;
|
|
else if (object == liq(CASK))
|
|
object = CASK;
|
|
|
|
if (!toting(object)) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (prep == PREPIN) {
|
|
vinsert();
|
|
return;
|
|
}
|
|
/* Snake and bird */
|
|
if (object == BIRD && here(SNAKE)) {
|
|
rspeak(30);
|
|
if (g.closed) {
|
|
dwarfend();
|
|
return;
|
|
}
|
|
extract(BIRD);
|
|
destroy(SNAKE);
|
|
/* Set snake prop for use by travel options */
|
|
g.prop[SNAKE] = 1;
|
|
drop(BIRD, g.loc);
|
|
return;
|
|
}
|
|
msg = 344;
|
|
if (verb == LEAVE)
|
|
msg = 353;
|
|
if (verb == THROW)
|
|
msg = 352;
|
|
if (verb == TAKE)
|
|
msg = 54;
|
|
if (object == POLE && holding(BOAT)) {
|
|
rspeak(280);
|
|
return;
|
|
}
|
|
/* Coins and vending machine */
|
|
if (object == COINS && here(VEND)) {
|
|
destroy(COINS);
|
|
drop(BATTERIES, g.loc);
|
|
pspeak(BATTERIES, 0);
|
|
return;
|
|
}
|
|
/* Bird and dragon (ouch!!) */
|
|
if (object == BIRD && at(DRAGON) && g.prop[DRAGON] == 0) {
|
|
rspeak(154);
|
|
extract(BIRD);
|
|
destroy(BIRD);
|
|
if (g.place[SNAKE] == plac[SNAKE])
|
|
g.tally2++;
|
|
return;
|
|
}
|
|
/* Bear and troll */
|
|
if (object == BEAR && at(TROLL)) {
|
|
msg = 163;
|
|
destroy(TROLL);
|
|
destroy(TROLL + MAXOBJ);
|
|
move(TROLL2, plac[TROLL]);
|
|
move((TROLL2 + MAXOBJ), fixd[TROLL]);
|
|
juggle(CHASM);
|
|
g.prop[TROLL] = 2;
|
|
}
|
|
/* Vase */
|
|
else if (object == VASE) {
|
|
if (g.loc == plac[PILLOW])
|
|
msg = 54;
|
|
else {
|
|
g.prop[VASE] = at(PILLOW) ? 0 : 2;
|
|
pspeak(VASE, g.prop[VASE] + 1);
|
|
if (g.prop[VASE] != 0)
|
|
g.fixed[VASE] = -1;
|
|
}
|
|
} else {
|
|
if (worn(object) || object == POLE || object == BOAT)
|
|
g.prop[object] = 0;
|
|
if (worn(object))
|
|
bitoff(object, WEARBT);
|
|
if (object == POLE)
|
|
g.prop[BOAT] = 0;
|
|
}
|
|
|
|
if (enclosed(object))
|
|
extract(object);
|
|
drop(object, g.loc);
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
OPEN. special stuff for opening clam/oyster.
|
|
The following can be opened without a key:
|
|
clam/oyster, door, pdoor, bottle, cask, cage
|
|
*/
|
|
void vopen()
|
|
{
|
|
int msg, oyclam;
|
|
|
|
if (!hinged(object))
|
|
msg = noway();
|
|
else if (object == PDOOR && g.prop[PDOOR] == 1)
|
|
msg = 253;
|
|
else if (ajar(object))
|
|
msg = 336;
|
|
else if (locks(object) || iobj == KEYS || iobj == SKEY) {
|
|
vunlock();
|
|
return;
|
|
} else if (locked(object))
|
|
if (object == DOOR)
|
|
msg = 111;
|
|
else
|
|
msg = 337;
|
|
else if (object == CLAM || object == OYSTER) {
|
|
oyclam = (object == OYSTER ? 1 : 0);
|
|
msg = oyclam + holding(object) ? 120 : 124;
|
|
if (!athand(TRIDENT))
|
|
msg = 122 + oyclam;
|
|
if (iobj != 0 && iobj != TRIDENT)
|
|
msg = 376 + oyclam;
|
|
|
|
if (msg == 124) {
|
|
destroy(CLAM);
|
|
drop(OYSTER, g.loc);
|
|
drop(PEARL, 105);
|
|
}
|
|
} else {
|
|
msg = 54;
|
|
biton(object, OPENBT);
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
close, shut
|
|
the following can be closed without keys:
|
|
door, pdoor, bottle, cask, cage
|
|
*/
|
|
void vclose()
|
|
{
|
|
if (!hinged(object))
|
|
rspeak(noway());
|
|
else if (!ajar(object))
|
|
rspeak(338);
|
|
else if (locks(object))
|
|
vlock();
|
|
else {
|
|
rspeak(54);
|
|
bitoff(object, OPENBT);
|
|
}
|
|
}
|
|
|
|
/*
|
|
Lamp ON.
|
|
*/
|
|
void von()
|
|
{
|
|
if (!athand(LAMP))
|
|
actspk(verb);
|
|
else if (g.limit < 0)
|
|
rspeak(184);
|
|
else if (g.prop[LAMP] == 1)
|
|
rspeak(321);
|
|
else {
|
|
g.prop[LAMP] = 1;
|
|
if (g.loc == 200)
|
|
rspeak(108);
|
|
else
|
|
rspeak(39);
|
|
if (g.wzdark) {
|
|
g.wzdark = 0;
|
|
describe();
|
|
descitem();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Lamp OFF.
|
|
*/
|
|
void voff()
|
|
{
|
|
if (!athand(LAMP))
|
|
actspk(verb);
|
|
else if (g.prop[LAMP] == 0)
|
|
rspeak(322);
|
|
else {
|
|
g.prop[LAMP] = 0;
|
|
rspeak(40);
|
|
if (dark())
|
|
rspeak(16);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
WAVE. no effect unless waving rod at fissure.
|
|
*/
|
|
void vwave()
|
|
{
|
|
if (!holding(object) &&
|
|
(object != ROD || !holding(ROD2)))
|
|
rspeak(29);
|
|
else if (object != ROD || !at(FISSURE) ||
|
|
!holding(object) || g.closing)
|
|
actspk(verb);
|
|
else if (iobj != 0 && iobj != FISSURE)
|
|
actspk(verb);
|
|
else {
|
|
g.prop[FISSURE] = 1 - g.prop[FISSURE];
|
|
pspeak(FISSURE, 2 - g.prop[FISSURE]);
|
|
if (g.chase == 0 || g.prop[FISSURE] != 0)
|
|
return;
|
|
if ((g.loc == 17 && g.oldloc != 27)
|
|
|| (g.loc == 27 && g.oldloc != 17))
|
|
return;
|
|
/* Demise of the Wumpus. Champ must have just crossed bridge */
|
|
rspeak(244);
|
|
g.chase = 0;
|
|
drop(RING, 209);
|
|
g.prop[WUMPUS] = 6;
|
|
move(WUMPUS, 209);
|
|
biton(WUMPUS, DEADBT);
|
|
if (g.place[AXE] != plac[WUMPUS])
|
|
return;
|
|
g.fixed[AXE] = 0;
|
|
g.prop[AXE] = 0;
|
|
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
ATTACK, KILL etc.
|
|
*/
|
|
void vkill()
|
|
{
|
|
int msg, i, k;
|
|
boolean survival;
|
|
|
|
survival = TRUE;
|
|
switch (object) {
|
|
case BIRD:
|
|
if (g.closed)
|
|
msg = 137;
|
|
else {
|
|
destroy(BIRD);
|
|
g.prop[BIRD] = 0;
|
|
if (g.place[SNAKE] == plac[SNAKE])
|
|
g.tally2++;
|
|
msg = 45;
|
|
}
|
|
break;
|
|
case DWARF:
|
|
if (g.closed) {
|
|
dwarfend();
|
|
return;
|
|
}
|
|
survival = do_battle(&msg);
|
|
break;
|
|
case 0:
|
|
msg = 44;
|
|
break;
|
|
case CLAM:
|
|
case OYSTER:
|
|
msg = 150;
|
|
break;
|
|
case DOG:
|
|
if (g.prop[DOG] == 1)
|
|
msg = 291;
|
|
else if (iobj == AXE) {
|
|
object = AXE;
|
|
iobj = DOG;
|
|
vthrow();
|
|
return;
|
|
} else
|
|
msg = 110;
|
|
break;
|
|
case SNAKE:
|
|
msg = 46;
|
|
break;
|
|
case TROLL:
|
|
if (iobj == AXE)
|
|
msg = 158;
|
|
else
|
|
msg = 110;
|
|
break;
|
|
case BEAR:
|
|
msg = 165 + (g.prop[BEAR] + 1) / 2;
|
|
break;
|
|
case WUMPUS:
|
|
if (g.prop[WUMPUS] == 6)
|
|
msg = 167;
|
|
else if (iobj == AXE) {
|
|
object = AXE;
|
|
iobj = WUMPUS;
|
|
vthrow();
|
|
return;
|
|
} else
|
|
msg = 110;
|
|
break;
|
|
case GNOME:
|
|
msg = 320;
|
|
break;
|
|
case DRAGON:
|
|
if (g.prop[DRAGON] != 0) {
|
|
msg = 167;
|
|
break;
|
|
}
|
|
if (!yes(49, 0, 0))
|
|
break;
|
|
pspeak(DRAGON, 1);
|
|
biton(DRAGON, DEADBT);
|
|
g.prop[DRAGON] = 2;
|
|
g.prop[RUG] = 0;
|
|
k = (plac[DRAGON] + fixd[DRAGON]) / 2;
|
|
move((DRAGON + MAXOBJ), -1);
|
|
move((RUG + MAXOBJ), 0);
|
|
move(DRAGON, k);
|
|
move(RUG, k);
|
|
for (i = 1; i < MAXOBJ; i++)
|
|
if (g.place[i] == plac[DRAGON]
|
|
|| g.place[i] == fixd[DRAGON]
|
|
|| holding(i))
|
|
move(i, k);
|
|
g.loc = k;
|
|
g.newloc = k;
|
|
return;
|
|
default:
|
|
actspk(verb);
|
|
return;
|
|
}
|
|
rspeak(msg);
|
|
if (!survival) {
|
|
g.oldloc2 = g.loc;
|
|
death();
|
|
}
|
|
return;
|
|
}
|
|
|
|
static boolean do_battle(msg_ptr)
|
|
int *msg_ptr;
|
|
{
|
|
boolean survival;
|
|
int temp;
|
|
|
|
survival = TRUE;
|
|
if (iobj == 0)
|
|
*msg_ptr = 49;
|
|
else if (iobj != AXE && iobj != SWORD) {
|
|
*msg_ptr = 355;
|
|
survival = FALSE;
|
|
} else if (pct(25)) {
|
|
temp = iobj;
|
|
iobj = object;
|
|
object = temp;
|
|
vthrow();
|
|
return (TRUE);
|
|
} else if (pct(25)) {
|
|
*msg_ptr = 355;
|
|
survival = FALSE;
|
|
} else if (pct(36))
|
|
*msg_ptr = 354;
|
|
else {
|
|
rspeak(356);
|
|
if (pct(61))
|
|
*msg_ptr = 52;
|
|
else {
|
|
*msg_ptr = 53;
|
|
survival = FALSE;
|
|
}
|
|
}
|
|
return (survival);
|
|
}
|
|
|
|
/*
|
|
POUR
|
|
*/
|
|
void vpour()
|
|
{
|
|
int msg;
|
|
|
|
if (object == BOTTLE || object == CASK) {
|
|
iobj = object;
|
|
object = liq(iobj);
|
|
if (object == 0) {
|
|
rspeak(316);
|
|
return;
|
|
}
|
|
} else {
|
|
if (object < WATER || object > (WINE + 1)) {
|
|
rspeak(78);
|
|
return;
|
|
}
|
|
}
|
|
if (!holding(BOTTLE) && !holding(CASK)) {
|
|
rspeak(29);
|
|
return;
|
|
}
|
|
if (holding(BOTTLE) && liq(BOTTLE) == object)
|
|
iobj = BOTTLE;
|
|
if (holding(CASK) && liq(CASK) == object)
|
|
iobj = CASK;
|
|
if (iobj == 0) {
|
|
rspeak(29);
|
|
return;
|
|
}
|
|
if (!ajar(iobj)) {
|
|
rspeak(335);
|
|
return;
|
|
}
|
|
if (iobj == CASK)
|
|
object++;
|
|
g.prop[iobj] = 1;
|
|
extract(object);
|
|
g.place[object] = 0;
|
|
msg = 77;
|
|
if (iobj == CASK) {
|
|
object--;
|
|
msg = 104;
|
|
}
|
|
if (at(PLANT) || at(DOOR) || (at(SWORD) && g.prop[SWORD] != 0)) {
|
|
if (at(DOOR)) {
|
|
g.prop[DOOR] = 0;
|
|
if (object == OIL) {
|
|
g.prop[DOOR] = 1;
|
|
bitoff(DOOR, LOCKBT);
|
|
biton(DOOR, OPENBT);
|
|
}
|
|
msg = 113 + g.prop[DOOR];
|
|
} else if (at(SWORD)) {
|
|
/* If sword is alread oily, don't let him clean it. No
|
|
soap. */
|
|
if (g.prop[SWORD] != 5) {
|
|
g.prop[SWORD] = 4;
|
|
if (object == OIL) {
|
|
g.prop[SWORD] = 5;
|
|
g.fixed[SWORD] = -1;
|
|
}
|
|
msg = 206 + g.prop[SWORD] - 4;
|
|
}
|
|
} else {
|
|
msg = 112;
|
|
if (object == WATER) {
|
|
if (g.prop[PLANT] < 0)
|
|
g.prop[PLANT] = -g.prop[PLANT] - 1;
|
|
pspeak(PLANT, g.prop[PLANT] + 1);
|
|
g.prop[PLANT] = (g.prop[PLANT] + 2) % 6;
|
|
g.prop[PLANT2] = g.prop[PLANT] / 2;
|
|
newtravel = TRUE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
EAT
|
|
If he ate the right thing and is in the right place, move him to
|
|
the other place with all his junk. Otherwise, narky message.
|
|
*/
|
|
void veat()
|
|
{
|
|
int msg, i, k, ll, kk;
|
|
|
|
switch (object) {
|
|
case HONEY:
|
|
g.tally2++;
|
|
case FOOD:
|
|
destroy(object);
|
|
msg = 72;
|
|
break;
|
|
case BIRD:
|
|
case SNAKE:
|
|
case CLAM:
|
|
case OYSTER:
|
|
case FLOWER:
|
|
msg = 301;
|
|
break;
|
|
case DWARF:
|
|
case DRAGON:
|
|
case TROLL:
|
|
case DOG:
|
|
case WUMPUS:
|
|
case BEAR:
|
|
case GNOME:
|
|
msg = 250;
|
|
break;
|
|
case MUSHRM:
|
|
case CAKES:
|
|
k = object - MUSHRM;
|
|
ll = 229 + k;
|
|
k = 159 - k;
|
|
kk = SKEY;
|
|
if (object == MUSHRM) {
|
|
kk = TDOOR;
|
|
if (g.loc != 158)
|
|
g.tally2++;
|
|
}
|
|
destroy(object);
|
|
msg = 228;
|
|
if (!(here(kk) || g.fixed[kk] == g.loc))
|
|
break;
|
|
msg = ll;
|
|
/* If he hasn't taken tiny key off shelf, don't let him get it
|
|
for free! */
|
|
for (i = 1; i < MAXOBJ; i++) {
|
|
if (i == SKEY && g.prop[SKEY] == 1)
|
|
continue;
|
|
if (g.place[i] == plac[kk] && g.fixed[i] == 0)
|
|
move(i, k);
|
|
}
|
|
if (g.loc == plac[SKEY] && g.place[SKEY] == plac[SKEY])
|
|
g.tally2++;
|
|
g.loc = k;
|
|
g.newloc = k;
|
|
newtravel = TRUE;
|
|
break;
|
|
default:
|
|
actspk(verb);
|
|
return;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
DRINK
|
|
*/
|
|
void vdrink()
|
|
{
|
|
int msg, k, j;
|
|
|
|
if (object == 0 && (iobj == BOTTLE || iobj == CASK))
|
|
object = liq(iobj);
|
|
msg = 110;
|
|
if (object == OIL)
|
|
msg = 301;
|
|
if (object != WATER && object != WINE) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (iobj == 0) {
|
|
if (object == liqloc(g.loc))
|
|
iobj = -1;
|
|
if (athand(CASK) && object == liq(CASK))
|
|
iobj = CASK;
|
|
if (athand(BOTTLE) && object == liq(BOTTLE))
|
|
iobj = BOTTLE;
|
|
}
|
|
msg = 73;
|
|
if (iobj != -1) {
|
|
if (iobj == CASK)
|
|
object++;
|
|
extract(object);
|
|
g.place[object] = 0;
|
|
g.prop[iobj] = 1;
|
|
msg = (iobj == CASK) ? 299 : 74;
|
|
}
|
|
if (object == WATER || object == (WATER + 1)) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
/* UH-OH. He's a wino. Let him reap the rewards of incontinence.
|
|
He'll wander around for awhile, then wake up somewhere or other,
|
|
having dropped most of his stuff. */
|
|
rspeak(300);
|
|
if (g.prop[LAMP] == 1)
|
|
g.limit -= ranz(g.limit) / 2;
|
|
if (g.limit < 10)
|
|
g.limit = 25;
|
|
k = 0;
|
|
if (pct(15))
|
|
k = 49;
|
|
if (k == 0 && pct(15))
|
|
k = 53;
|
|
if (k == 0 && pct(25))
|
|
k = 132;
|
|
if (k == 0)
|
|
k = 175;
|
|
if (outside(g.loc))
|
|
k = 5;
|
|
if (k == g.loc) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (holding(AXE))
|
|
move(AXE, k);
|
|
if (holding(LAMP))
|
|
move(LAMP, k);
|
|
for (j = 1; j < MAXOBJ; j++) {
|
|
if (wearng(j))
|
|
bitoff(j, WEARBT);
|
|
if (holding(j))
|
|
drop(j, g.loc);
|
|
}
|
|
g.loc = k;
|
|
g.newloc = k;
|
|
}
|
|
|
|
/*
|
|
THROW etc.
|
|
*/
|
|
void vthrow()
|
|
{
|
|
int msg, i, k, dwarfn;
|
|
|
|
if (holding(ROD2) && object == ROD && !holding(ROD))
|
|
object = ROD2;
|
|
if (!holding(object)) {
|
|
actspk(verb);
|
|
return;
|
|
}
|
|
if (object == BOAT || object == BEAR) {
|
|
rspeak(noway());
|
|
return;
|
|
}
|
|
dwarfn = dcheck();
|
|
if (iobj == 0) {
|
|
/* No indirect object was specified. If a dwarf is present,
|
|
assume it is the object. If not, look for other living
|
|
thing. If no living things present, treat 'THROW' as 'DROP'. */
|
|
|
|
if (dwarfn)
|
|
iobj = DWARF;
|
|
else {
|
|
/* No dwarves present; figure out pausible object. */
|
|
k = 0;
|
|
for (i = 1; i < MAXOBJ; i++) {
|
|
if (at(i) && living(i)) {
|
|
iobj = i;
|
|
k++;
|
|
}
|
|
}
|
|
if (k == 0) {
|
|
vdrop();
|
|
return;
|
|
}
|
|
/* It is a beastie of some sort. Is there more than one?
|
|
Don't kill the bird by default. */
|
|
if (k > 1) {
|
|
rspeak(43);
|
|
return;
|
|
} else {
|
|
if (iobj == BIRD) {
|
|
vdrop();
|
|
return;
|
|
}
|
|
if (treasr(object) && at(TROLL))
|
|
iobj = TROLL;
|
|
}
|
|
}
|
|
}
|
|
if (object == SWORD || object == BOTTLE) {
|
|
vbreak();
|
|
return;
|
|
}
|
|
if (object == FLOWER && iobj == HIVE)
|
|
iobj = BEES;
|
|
if (edible(object) && living(iobj)) {
|
|
vfeed();
|
|
return;
|
|
}
|
|
/* If not axe, same as drop... */
|
|
if (object != AXE && iobj != TROLL) {
|
|
vdrop();
|
|
return;
|
|
}
|
|
/* AXE is THROWN */
|
|
msg = 48;
|
|
switch (iobj) {
|
|
case DRAGON:
|
|
if (g.prop[DRAGON] == 0)
|
|
msg = 152;
|
|
break;
|
|
case DWARF:
|
|
/* At a dwarf... */
|
|
if (pct(75)) {
|
|
g.dseen[dwarfn] = g.dloc[dwarfn] = 0;
|
|
msg = 47;
|
|
++g.dkill;
|
|
if (g.dkill == 1)
|
|
msg = 149;
|
|
}
|
|
break;
|
|
case BEAR:
|
|
/* This'll teach him to throw axe at the bear */
|
|
if (g.prop[BEAR] == 0) {
|
|
msg = 164;
|
|
drop(AXE, g.loc);
|
|
g.fixed[AXE] = -1;
|
|
g.prop[AXE] = 1;
|
|
juggle(BEAR);
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
case WUMPUS:
|
|
/* Or the WUMPUS! */
|
|
if (g.prop[WUMPUS] == 6) {
|
|
vdrop();
|
|
return;
|
|
} else {
|
|
msg = 245;
|
|
g.prop[AXE] = 2;
|
|
if (g.prop[WUMPUS] == 0) {
|
|
drop(AXE, g.loc);
|
|
g.fixed[AXE] = -1;
|
|
juggle(iobj);
|
|
} else {
|
|
msg = 243;
|
|
destroy(AXE);
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
case DOG:
|
|
/* Or the nice doggie! */
|
|
if (g.prop[DOG] != 1) {
|
|
msg = 248;
|
|
g.prop[AXE] = 3;
|
|
drop(AXE, g.loc);
|
|
g.fixed[AXE] = -1;
|
|
juggle(iobj);
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
case TROLL:
|
|
/* Snarf a treasure for the troll */
|
|
if (object == AXE) {
|
|
msg = 158;
|
|
} else if (!treasr(object) ||
|
|
(object == CASK && (liq(CASK) != WINE))) {
|
|
vdrop();
|
|
return;
|
|
} else {
|
|
msg = 159;
|
|
drop(object, 0);
|
|
if (object == CASK)
|
|
g.place[WINE + 1] = 0;
|
|
move(TROLL, 0);
|
|
move((TROLL + MAXOBJ), 0);
|
|
drop(TROLL2, plac[TROLL]);
|
|
drop((TROLL2 + MAXOBJ), fixd[TROLL]);
|
|
juggle(CHASM);
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Otherwise it is an attack */
|
|
verb = KILL;
|
|
object = iobj;
|
|
iobj = objs[objx];
|
|
vkill();
|
|
return;
|
|
}
|
|
|
|
rspeak(msg);
|
|
drop(AXE, g.loc);
|
|
g.newloc = g.loc;
|
|
describe();
|
|
}
|
|
|
|
/*
|
|
FIND might be carrying it, or it might be here. else give caveat.
|
|
*/
|
|
void vfind()
|
|
{
|
|
int msg;
|
|
|
|
if (at(object) ||
|
|
(liq(BOTTLE) == object && at(BOTTLE)) ||
|
|
object == liqloc(g.loc))
|
|
msg = 94;
|
|
else if (dcheck() && g.dflag >= 2 && object == DWARF)
|
|
msg = 94;
|
|
else if (g.closed)
|
|
msg = 138;
|
|
else if (at(object))
|
|
msg = 24;
|
|
else {
|
|
actspk(verb);
|
|
return;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
FEED
|
|
*/
|
|
void vfeed()
|
|
{
|
|
int msg;
|
|
|
|
if (iobj == 0 || !living(iobj)) {
|
|
int i, k, kk;
|
|
|
|
if (object == BIRD) {
|
|
rspeak(100);
|
|
return;
|
|
}
|
|
if (!living(object)) {
|
|
rspeak(noway());
|
|
return;
|
|
}
|
|
/* See if there is anything edible around here. */
|
|
|
|
kk = 0;
|
|
k = 0;
|
|
for (i = 1; i < MAXOBJ; i++)
|
|
if (here(i) && edible(i)) {
|
|
k++;
|
|
kk = i;
|
|
}
|
|
iobj = object;
|
|
object = kk;
|
|
if (k != 1 && !dead(iobj)) {
|
|
printf("What do you want to feed the %s\n", otxt[objx]);
|
|
objs[1] = 0;
|
|
objx = 0;
|
|
return;
|
|
}
|
|
}
|
|
/* Feed object ot indirect object */
|
|
msg = 102;
|
|
switch (iobj) {
|
|
case DRAGON:
|
|
if (g.prop[DRAGON] != 0)
|
|
msg = noway();
|
|
break;
|
|
case TROLL:
|
|
msg = 182;
|
|
break;
|
|
case SNAKE:
|
|
if (object == BIRD && !g.closed) {
|
|
msg = 101;
|
|
destroy(BIRD);
|
|
g.prop[BIRD] = 0;
|
|
g.tally2++;
|
|
}
|
|
break;
|
|
case DWARF:
|
|
msg = 103;
|
|
g.dflag++;
|
|
break;
|
|
case BEAR:
|
|
if (g.prop[BEAR] == 3)
|
|
msg = noway();
|
|
if (g.prop[BEAR] == 1 || g.prop[BEAR] == 2)
|
|
msg = 264;
|
|
if (object == FOOD)
|
|
msg = 278;
|
|
if (object == HONEY) {
|
|
g.prop[BEAR] = 1;
|
|
g.fixed[AXE] = 0;
|
|
destroy(HONEY);
|
|
msg = 168;
|
|
}
|
|
break;
|
|
case DOG:
|
|
msg = 291;
|
|
if (object == FOOD && g.prop[DOG] != 1) {
|
|
msg = 249;
|
|
destroy(FOOD);
|
|
}
|
|
break;
|
|
case WUMPUS:
|
|
if (g.prop[WUMPUS] == 6)
|
|
msg = 326;
|
|
if (g.prop[WUMPUS] == 0)
|
|
msg = 327;
|
|
if (object == FOOD)
|
|
msg = 240;
|
|
break;
|
|
case BEES:
|
|
if (object == FLOWER) {
|
|
if (enclosed(FLOWER))
|
|
extract(FLOWER);
|
|
drop(FLOWER, g.loc);
|
|
g.fixed[FLOWER] = -1;
|
|
g.prop[FLOWER] = 1;
|
|
drop(HONEY, g.loc);
|
|
juggle(HONEY);
|
|
msg = 267;
|
|
g.prop[HIVE] = 1;
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
FILL. object with iobj
|
|
*/
|
|
void vfill()
|
|
{
|
|
int msg, k;
|
|
|
|
if (!vessel(object))
|
|
msg = 313;
|
|
else {
|
|
if (iobj == 0)
|
|
iobj = liqloc(g.loc);
|
|
if (object == BOTTLE || object == CASK) {
|
|
k = (object == CASK) ? 1 : 0;
|
|
msg = 0;
|
|
if (iobj == 0)
|
|
msg = 304 + k;
|
|
if (liq(object) != 0)
|
|
msg = 302 + k;
|
|
if (msg != 0) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
msg = 306 + k;
|
|
if (iobj == OIL)
|
|
msg = 308 + k;
|
|
if (iobj == WINE)
|
|
msg = 310 + k;
|
|
g.prop[object] = (int) g.loc_attrib[g.loc] & 14;
|
|
g.place[iobj + k] = -1;
|
|
insert(iobj + k, object);
|
|
} else if (object == VASE) {
|
|
if (iobj == 0 || !holding(VASE)) {
|
|
rspeak(144);
|
|
return;
|
|
}
|
|
msg = 145;
|
|
g.prop[VASE] = 2;
|
|
g.fixed[VASE] = -1;
|
|
if (enclosed(object))
|
|
extract(object);
|
|
drop(object, g.loc);
|
|
} else if (object == GRAIL)
|
|
msg = 298;
|
|
else
|
|
msg = 339;
|
|
}
|
|
rspeak(msg);
|
|
}
|
|
|
|
/*
|
|
READ. Magazine in dwarvish, message we've seen, and ... oyster?
|
|
*/
|
|
void vread()
|
|
{
|
|
int msg;
|
|
|
|
if (blind()) {
|
|
actspk(verb);
|
|
return;
|
|
}
|
|
if (object && iobj) {
|
|
rspeak(confuz());
|
|
return;
|
|
}
|
|
msg = confuz();
|
|
if (!object)
|
|
object = iobj;
|
|
switch (object) {
|
|
case BOOK:
|
|
case BOOK2:
|
|
msg = 142;
|
|
break;
|
|
case BILLBD:
|
|
msg = 361;
|
|
break;
|
|
case CARVNG:
|
|
msg = 372;
|
|
break;
|
|
case MAGAZINE:
|
|
msg = 190;
|
|
break;
|
|
case MESSAGE:
|
|
msg = 191;
|
|
break;
|
|
case POSTER:
|
|
msg = 370;
|
|
break;
|
|
case TABLET:
|
|
msg = 196;
|
|
break;
|
|
case OYSTER:
|
|
if (g.hinted[2] && holding(OYSTER))
|
|
msg = 194;
|
|
if (!g.hinted[2] && holding(OYSTER) && g.closed) {
|
|
g.hinted[2] = yes(192, 193, 54);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
BREAK. works for mirror in repository and, of course the
|
|
vase and bottle. Also the sword is more brittle than it appears.
|
|
*/
|
|
void vbreak()
|
|
{
|
|
int msg, k;
|
|
boolean it_broke;
|
|
|
|
it_broke = FALSE;
|
|
msg = 146;
|
|
switch (object) {
|
|
case MIRROR:
|
|
msg = 148;
|
|
if (g.closed) {
|
|
rspeak(197);
|
|
dwarfend();
|
|
return;
|
|
}
|
|
break;
|
|
case VASE:
|
|
if (g.prop[VASE] == 0) {
|
|
it_broke = TRUE;
|
|
msg = 198;
|
|
g.prop[VASE] = 2;
|
|
}
|
|
break;
|
|
case BOTTLE:
|
|
if (g.prop[BOTTLE] != 3) {
|
|
it_broke = TRUE;
|
|
k = liq(BOTTLE);
|
|
msg = 231;
|
|
g.prop[BOTTLE] = 3;
|
|
if (k) {
|
|
extract(k);
|
|
g.place[k] = 0;
|
|
}
|
|
}
|
|
break;
|
|
case SWORD:
|
|
msg = 29;
|
|
if (holding(SWORD)) {
|
|
msg = 279;
|
|
g.prop[SWORD] = 4;
|
|
it_broke = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
if (it_broke) {
|
|
if (enclosed(object))
|
|
extract(object);
|
|
if (holding(object))
|
|
drop(object, g.loc);
|
|
g.fixed[object] = -1;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
WAKE. only use is to disturb the dwarves or the Wumpus.
|
|
Other wumpus-wakers link here.
|
|
*/
|
|
void vwake()
|
|
{
|
|
int msg;
|
|
|
|
msg = actmsg[verb];
|
|
if (at(WUMPUS)) {
|
|
g.chase = TRUE;
|
|
g.prop[WUMPUS] = 1;
|
|
msg = 276;
|
|
}
|
|
if (at(DOG) && g.prop[DOG] == 1)
|
|
msg = 291;
|
|
if (object == DWARF && g.closed) {
|
|
rspeak(199);
|
|
dwarfend();
|
|
return;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
YANK. A variant of 'CARRY'. In general, not a good idea.
|
|
At most, it gets the cloak or a couple of snide comments.
|
|
*/
|
|
void vyank()
|
|
{
|
|
if (toting(object))
|
|
vdrop();
|
|
else if (object == BEAR && g.prop[CHAIN])
|
|
rspeak(205);
|
|
else if (object == CLOAK && g.prop[CLOAK] == 2) {
|
|
/* Cloak. big trouble ahead. */
|
|
g.prop[ROCKS] = 1;
|
|
g.prop[CLOAK] = 0;
|
|
g.fixed[CLOAK] = 0;
|
|
carry(CLOAK, g.loc);
|
|
rspeak(241);
|
|
if (at(WUMPUS) && g.prop[WUMPUS] == 0) {
|
|
g.chase = 1;
|
|
g.prop[WUMPUS] = 1;
|
|
rspeak(276);
|
|
}
|
|
} else
|
|
vtake();
|
|
return;
|
|
}
|
|
|
|
/*
|
|
WEAR. Only good for jewels, ruby slippers, cloak & crown.
|
|
But he might try the sword. Anything else is ridiculous.
|
|
Another variant of 'CARRY'.
|
|
*/
|
|
void vwear()
|
|
{
|
|
int msg;
|
|
|
|
if (object == SWORD && g.prop[SWORD] != 3)
|
|
msg = 209;
|
|
else if (worn(object)) {
|
|
if (object == CLOAK && g.prop[CLOAK] == 2)
|
|
msg = 242;
|
|
else if (wearng(object))
|
|
msg = (object == SHOES) ? 227 : 210;
|
|
else {
|
|
g.prop[object] = 1;
|
|
biton(object, WEARBT);
|
|
if (enclosed(object))
|
|
extract(object);
|
|
if (holding(object))
|
|
msg = 54;
|
|
else {
|
|
vtake();
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
printf("Just exactly how does one wear a %s\n", otxt[objx]);
|
|
return;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
HIT. If not punching out telephone, assume attack.
|
|
*/
|
|
void vhit()
|
|
{
|
|
if (at(WUMPUS) && g.prop[WUMPUS] == 0) {
|
|
vwake();
|
|
return;
|
|
}
|
|
if (object != PHONE) {
|
|
vkill();
|
|
return;
|
|
} else {
|
|
if (g.closed) {
|
|
rspeak(282);
|
|
dwarfend();
|
|
return;
|
|
}
|
|
if (g.prop[PHONE] == 2)
|
|
rspeak(256);
|
|
else {
|
|
drop(SLUGS, g.loc);
|
|
g.prop[PHONE] = 2;
|
|
g.prop[BOOTH] = 2;
|
|
rspeak(257);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
ANSWER (telephone). Smartass for anything else.
|
|
*/
|
|
void vanswer()
|
|
{
|
|
int msg;
|
|
|
|
switch (object) {
|
|
case DWARF:
|
|
case WUMPUS:
|
|
case SNAKE:
|
|
case BEAR:
|
|
case DRAGON:
|
|
msg = 259;
|
|
break;
|
|
case TROLL:
|
|
msg = 258;
|
|
break;
|
|
case BIRD:
|
|
msg = 260;
|
|
break;
|
|
case PHONE:
|
|
if (g.prop[PHONE] != 0)
|
|
msg = 269;
|
|
else if (g.closed) {
|
|
rspeak(283);
|
|
normend();
|
|
return;
|
|
} else {
|
|
msg = 261;
|
|
g.prop[PHONE] = 1;
|
|
g.prop[BOOTH] = 2;
|
|
}
|
|
break;
|
|
default:
|
|
msg = actmsg[verb];
|
|
break;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
BLOW. Joshua fit de battle of Jericho, and de walls ...
|
|
*/
|
|
void vblow()
|
|
{
|
|
int msg, i, k;
|
|
|
|
msg = actmsg[verb];
|
|
if (object != 0 && iobj != 0) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (object == 0)
|
|
object = iobj;
|
|
iobj = 0;
|
|
if (object == 0)
|
|
msg = 268;
|
|
if (object == HORN) {
|
|
msg = outside(g.loc) ? 277 : 266;
|
|
if (at(WUMPUS)) {
|
|
rspeak(msg);
|
|
if (g.prop[WUMPUS] == 0)
|
|
vwake();
|
|
return;
|
|
} else if (g.prop[WALL] != 1 && (g.loc == 102 || g.loc == 194)) {
|
|
k = g.loc == 194 ? 195 : 196;
|
|
msg = 265;
|
|
g.prop[WALL] = 1;
|
|
for (i = 1; i < MAXOBJ; i++)
|
|
if (g.place[i] == g.loc || g.fixed[i] == g.loc)
|
|
move(i, k);
|
|
g.newloc = k;
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
DIAL. No effect unless at phone.
|
|
*/
|
|
void vdial()
|
|
{
|
|
if (object != PHONE)
|
|
actspk(verb);
|
|
else if (g.closed) {
|
|
rspeak(283);
|
|
normend();
|
|
} else
|
|
rspeak(271);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
PLAY. Only for horn or lyre.
|
|
*/
|
|
void vplay()
|
|
{
|
|
int msg;
|
|
|
|
msg = actmsg[verb];
|
|
if (object != 0 && iobj != 0) {
|
|
rspeak(confuz());
|
|
return;
|
|
}
|
|
if (object == 0)
|
|
object = iobj;
|
|
if (object == HORN) {
|
|
vblow();
|
|
return;
|
|
}
|
|
if (object == LYRE) {
|
|
msg = 287;
|
|
if (here(DOG) && !dead(DOG)) {
|
|
g.prop[DOG] = 1;
|
|
biton(DOG, DEADBT);
|
|
g.fixed[AXE] = 0;
|
|
g.prop[AXE] = 0;
|
|
msg = 288;
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
PICK/ PICK UP. Can pick flower & mushrooms,
|
|
But must 'PICK UP' everything else.
|
|
*/
|
|
void vpick()
|
|
{
|
|
if (object == 0)
|
|
object = iobj;
|
|
iobj = 0;
|
|
if (object == FLOWER || object == MUSHRM || prep != 0)
|
|
vtake();
|
|
else
|
|
rspeak(confuz());
|
|
return;
|
|
}
|
|
|
|
/*
|
|
PUT DOWN: equivalent to drop
|
|
PUT IN: if liquid, means fill
|
|
PUT ON: wear of drop
|
|
*/
|
|
void vput()
|
|
{
|
|
if (prep == 0) {
|
|
printf("Where do you want to put the %s\n", otxt[objx]);
|
|
return;
|
|
}
|
|
if (prep == PREPIN)
|
|
vinsert();
|
|
else {
|
|
/* PUT ON: wear or put object on iobj */
|
|
if (prep == PREPON) {
|
|
if (object == 0) {
|
|
object = iobj;
|
|
otxt[objx] = iotxt[iobx];
|
|
iobj = 0;
|
|
}
|
|
if (worn(object) || object == 0)
|
|
vwear();
|
|
else
|
|
vdrop();
|
|
} else {
|
|
/* PUT DOWN: "drop" */
|
|
if (object == 0 && iobj == 0) {
|
|
if (object == 0)
|
|
object = iobj;
|
|
iobj = 0;
|
|
vdrop();
|
|
} else
|
|
rspeak(noway());
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/* turn on/off */
|
|
void vturn()
|
|
{
|
|
if (!prep)
|
|
rspeak(confuz());
|
|
else {
|
|
if (!object && iobj == LAMP)
|
|
object = LAMP;
|
|
if (object != LAMP)
|
|
rspeak(noway());
|
|
else if (prep == PREPON)
|
|
von();
|
|
else
|
|
voff();
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
GET (no prep): "take"
|
|
GET IN: "enter"
|
|
GET OUT: "leave"
|
|
*/
|
|
void vget()
|
|
{
|
|
if (prep == 0 || prep == PREPFR)
|
|
vtake();
|
|
else if (object == 0) {
|
|
object = iobj;
|
|
iobj = 0;
|
|
prep = 0;
|
|
vtake();
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
INSERT/PUT IN
|
|
*/
|
|
void vinsert()
|
|
{
|
|
int msg;
|
|
|
|
if (iobj == 0) {
|
|
printf("Where do you want to %s it?\n", vtxt[vrbx]);
|
|
return;
|
|
}
|
|
msg = noway();
|
|
if (object == SWORD && iobj == ANVIL && g.prop[SWORD] == 0)
|
|
msg = 350;
|
|
if (!vessel(iobj)) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
msg = ck_obj();
|
|
if (g.fixed[object]) {
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (object == iobj) {
|
|
rspeak(252);
|
|
return;
|
|
}
|
|
if (iobj == BOTTLE || iobj == CASK || iobj == VASE
|
|
|| iobj == GRAIL || (object >= WATER && object <= WINE + 1)) {
|
|
object = iobj;
|
|
iobj = objs[objx];
|
|
vfill();
|
|
return;
|
|
}
|
|
if (!ajar(iobj)) {
|
|
rspeak(358);
|
|
return;
|
|
}
|
|
if (iobj == CHEST) {
|
|
if (object == BOAT)
|
|
msg = noway();
|
|
else {
|
|
if (wearng(object))
|
|
bitoff(object, WEARBT);
|
|
if (worn(object))
|
|
g.prop[object] = 0;
|
|
if (enclosed(object))
|
|
extract(object);
|
|
insert(object, iobj);
|
|
msg = 54;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
/* Bird goes into cage and only cage */
|
|
if (object == BIRD && iobj != CAGE) {
|
|
rspeak(351);
|
|
return;
|
|
}
|
|
if (object != BIRD && iobj == CAGE) {
|
|
rspeak(329);
|
|
return;
|
|
}
|
|
if (object == BIRD) {
|
|
prep = 0;
|
|
vtake();
|
|
return;
|
|
}
|
|
/* Bar vase & pillow from safe, to force putting down on florr */
|
|
if ((object == VASE || object == PILLOW) && iobj == SAFE) {
|
|
rspeak(329);
|
|
return;
|
|
}
|
|
if (object != RADIUM && iobj == SHIELD) {
|
|
rspeak(329);
|
|
return;
|
|
}
|
|
if (iobj == PHONE) {
|
|
if (object == COINS || object == SLUGS) {
|
|
destroy(object);
|
|
msg = 330;
|
|
} else
|
|
msg = 329;
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (iobj == VEND) {
|
|
if (object == COINS || object == SLUGS) {
|
|
destroy(object);
|
|
move(BATTERIES, g.loc);
|
|
if (g.prop[BATTERIES] == 1) {
|
|
rspeak(317);
|
|
g.prop[VEND] = 1;
|
|
}
|
|
g.prop[BATTERIES] = 0;
|
|
pspeak(BATTERIES, 0);
|
|
} else
|
|
rspeak(noway());
|
|
return;
|
|
}
|
|
/* Put batteries in lamp. There is a glitch here, in that if he
|
|
tries to get a third set of batteries before the second set has
|
|
been inserted, the second set disappears!
|
|
***fix this some time ***
|
|
*/
|
|
if (iobj == LAMP) {
|
|
if (object != BATTERIES || g.prop[BATTERIES] != 0)
|
|
msg = noway();
|
|
else {
|
|
g.prop[BATTERIES] = 1;
|
|
if (enclosed(BATTERIES))
|
|
extract(BATTERIES);
|
|
if (holding(BATTERIES))
|
|
drop(BATTERIES, g.loc);
|
|
g.limit = 400;
|
|
g.prop[LAMP] = 1;
|
|
g.lmwarn = FALSE;
|
|
msg = 188;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
if (!small(object))
|
|
msg = 329;
|
|
else {
|
|
if (wearng(object))
|
|
bitoff(object, WEARBT);
|
|
if (worn(object))
|
|
g.prop[object] = 0;
|
|
if (enclosed(object))
|
|
extract(object);
|
|
insert(object, iobj);
|
|
msg = 54;
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
|
|
}
|
|
|
|
/* Remove or take from */
|
|
void vextract()
|
|
{
|
|
int msg;
|
|
|
|
if (object == RING && g.prop[RING] == 2) {
|
|
prep = 0;
|
|
iobj = 0;
|
|
vtake();
|
|
return;
|
|
}
|
|
msg = 343;
|
|
if (iobj == 0) {
|
|
if (!enclosed(object))
|
|
msg = 340;
|
|
iobj = -g.place[object];
|
|
}
|
|
if (g.place[object] != -iobj)
|
|
msg = 341;
|
|
if (!ajar(iobj))
|
|
msg = 335;
|
|
if (object == WATER || object == OIL || object == WINE)
|
|
msg = 342;
|
|
if (!toting(object) && ((burden(0) + burden(object)) > 15))
|
|
msg = 92;
|
|
if (msg == 343) {
|
|
if (object == BIRD) {
|
|
vdrop();
|
|
return;
|
|
}
|
|
extract(object);
|
|
}
|
|
rspeak(msg);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
lock. chain, grate, chest, elfin door
|
|
Here are the current lock/unlock messages & numbers:
|
|
31 you have no keys.
|
|
32 it has no lock.
|
|
34 it's already locked.
|
|
35 the grate is now locked.
|
|
36 the grate is now unlocked.
|
|
37 it was allready unlocked.
|
|
55 you can't unlock the keys.
|
|
171 The chain is now unlocked.
|
|
172 The chain is now locked.
|
|
173 There is nothing here to which the chain can be locked.
|
|
224 Your keys are all too large.
|
|
234 The wrought-iron door is now locked.
|
|
235 The tiny door is now locked.
|
|
236 The wrought-iron door is now unlocked.
|
|
237 The tiny door is now unlocked.
|
|
375 You don't have the right key.
|
|
333 the chest is now locked.
|
|
334 the chest is now unlocked.
|
|
367 The safe's door swings shut.
|
|
*/
|
|
void vlock()
|
|
{
|
|
int msg, k;
|
|
|
|
if (!hinged(object))
|
|
{
|
|
printf("I don't know how to lock or unlock the %s\n",
|
|
otxt[objx]);
|
|
return;
|
|
}
|
|
else if (!locks(object))
|
|
msg = 32;
|
|
else if (locked(object))
|
|
msg = 34;
|
|
else if (!athand(KEYS) && !athand(SKEY) && object != SAFE)
|
|
msg = 31;
|
|
else {
|
|
msg = 375;
|
|
switch (object) {
|
|
case CHAIN:
|
|
if (!athand(KEYS))
|
|
break;
|
|
msg = 173;
|
|
if (g.loc != plac[CHAIN])
|
|
break;
|
|
msg = 172;
|
|
g.prop[CHAIN] = 2;
|
|
if (enclosed(CHAIN))
|
|
extract(CHAIN);
|
|
if (holding(CHAIN))
|
|
drop(CHAIN, g.loc);
|
|
g.fixed[CHAIN] = -1;
|
|
biton(CHAIN, LOCKBT);
|
|
bitoff(CHAIN, OPENBT);
|
|
break;
|
|
|
|
case CHEST:
|
|
if (!athand(KEYS))
|
|
break;
|
|
msg = 334;
|
|
biton(CHEST, LOCKBT);
|
|
bitoff(CHEST, OPENBT);
|
|
break;
|
|
|
|
case TDOOR:
|
|
case TDOOR2:
|
|
msg = 224;
|
|
if (!toting(SKEY))
|
|
break;
|
|
g.prop[TDOOR] = 0;
|
|
g.prop[TDOOR2] = 0;
|
|
msg = 234 + (TDOOR2 - object);
|
|
k = TDOOR + TDOOR2 - object;
|
|
biton(k, LOCKBT);
|
|
bitoff(k, OPENBT);
|
|
biton(object, LOCKBT);
|
|
bitoff(object, OPENBT);
|
|
break;
|
|
|
|
case GRATE:
|
|
if (!athand(KEYS))
|
|
break;
|
|
g.prop[GRATE] = 0;
|
|
msg = 35;
|
|
biton(GRATE, LOCKBT);
|
|
bitoff(GRATE, OPENBT);
|
|
break;
|
|
|
|
case SAFE:
|
|
g.prop[SAFE] = 0;
|
|
msg = 367;
|
|
biton(SAFE, LOCKBT);
|
|
bitoff(SAFE, OPENBT);
|
|
break;
|
|
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
}
|
|
|
|
/*
|
|
UNLOCK. chain, grate, chest, elfin door.
|
|
*/
|
|
void vunlock()
|
|
{
|
|
int msg, k;
|
|
|
|
if (object == KEYS || object == SKEY)
|
|
msg = 55;
|
|
else if (!hinged(object))
|
|
{
|
|
printf("I don't know how to lock or unlock the %s\n",
|
|
otxt[objx]);
|
|
return;
|
|
}
|
|
else if (!locked(object))
|
|
msg = 37;
|
|
else if (!locks(object))
|
|
msg = 32;
|
|
else if (object == SAFE) {
|
|
if (iobj == KEYS || iobj == SKEY)
|
|
msg = 368;
|
|
else
|
|
msg = 342;
|
|
} else if (!athand(KEYS) && !athand(SKEY))
|
|
msg = 31;
|
|
else {
|
|
msg = 375;
|
|
switch (object) {
|
|
case CHAIN:
|
|
if (!athand(KEYS))
|
|
break;
|
|
if (g.prop[BEAR] == 0)
|
|
msg = 41;
|
|
else {
|
|
msg = 171;
|
|
g.prop[CHAIN] = 0;
|
|
g.fixed[CHAIN] = 0;
|
|
if (g.prop[BEAR] != 3)
|
|
g.prop[BEAR] = 2;
|
|
g.fixed[BEAR] = 2 - g.prop[BEAR];
|
|
bitoff(CHAIN, LOCKBT);
|
|
biton(CHAIN, OPENBT);
|
|
}
|
|
break;
|
|
case CHEST:
|
|
if (athand(KEYS)) {
|
|
msg = 333;
|
|
bitoff(CHEST, LOCKBT);
|
|
biton(CHEST, OPENBT);
|
|
}
|
|
break;
|
|
case TDOOR:
|
|
case TDOOR2:
|
|
/* Elvin door stuff to lock/unlock tiny door w/special key.
|
|
the damn thing is really at four places, and we want the
|
|
right messages if he only has 'BIG'keys (or no keys).
|
|
Also, he can unlock it either while he is big or small. */
|
|
msg = 224;
|
|
if (!athand(SKEY))
|
|
break;
|
|
if (g.closing) {
|
|
msg = 130;
|
|
if (!g.panic)
|
|
g.clock2 = 15;
|
|
g.panic = TRUE;
|
|
} else {
|
|
g.prop[TDOOR] = 1;
|
|
g.prop[TDOOR2] = 1;
|
|
msg = 234 + 2 + (TDOOR2 - object);
|
|
k = TDOOR + (TDOOR2 - object);
|
|
bitoff(k, LOCKBT);
|
|
biton(k, OPENBT);
|
|
bitoff(object, LOCKBT);
|
|
biton(object, OPENBT);
|
|
}
|
|
break;
|
|
case GRATE:
|
|
if (!athand(KEYS))
|
|
break;
|
|
if (g.closing) {
|
|
msg = 130;
|
|
if (!g.panic)
|
|
g.clock2 = 15;
|
|
g.panic = TRUE;
|
|
} else {
|
|
g.prop[GRATE] = 1;
|
|
msg = 36;
|
|
bitoff(GRATE, LOCKBT);
|
|
biton(GRATE, OPENBT);
|
|
}
|
|
break;
|
|
default:
|
|
msg = 33;
|
|
}
|
|
}
|
|
rspeak(msg);
|
|
}
|
|
|
|
/*
|
|
LOOK.
|
|
*/
|
|
void vlook()
|
|
{
|
|
int sloc;
|
|
|
|
if (object != 0) {
|
|
rspeak(confuz());
|
|
return;
|
|
}
|
|
/* Look into something (a container). */
|
|
if (vessel(iobj)) {
|
|
if (!ajar(iobj) && opaque(iobj))
|
|
rspeak(actmsg[verb]);
|
|
else if (g.holder[iobj] == 0)
|
|
rspeak(359);
|
|
else {
|
|
putchar(' ');
|
|
lookin(iobj);
|
|
}
|
|
|
|
/* Look at something. If written, read it. */
|
|
} else if (printed(iobj)) {
|
|
object = iobj;
|
|
iobj = 0;
|
|
vread();
|
|
} else if (iobj == SPHERE) {
|
|
if (!inside(g.loc) || athand(SAPPHIRE))
|
|
rspeak(42);
|
|
else {
|
|
rspeak(400);
|
|
printf(" ");
|
|
sloc = g.place[SAPPHIRE];
|
|
if ((g.loc_attrib[sloc] % 2 == 0 || enclosed(SAPPHIRE))
|
|
&& sloc != 200
|
|
&& !g.place[LAMP] == sloc && g.prop[LAMP] != 0)
|
|
rspeak(401);
|
|
else
|
|
desclg(sloc);
|
|
if (sloc == 239 && !g.flg239) {
|
|
rspeak(403);
|
|
g.flg239 = TRUE;
|
|
}
|
|
printf(" ");
|
|
rspeak(402);
|
|
}
|
|
} else
|
|
printf("I see nothing special about the %s?\n", iotxt[iobx]);
|
|
return;
|
|
}
|