📄 tess.c
字号:
/*--------------------------------------------------------------------------*\
| TESS.C |
\*--------------------------------------------------------------------------*/
/*
Beyond The Tesseract V2.03 (C) 1990 David Lo
TRS-80
1.0 : 05/29/83 :
1.7 : 03/16/86 :
MS-DOS
2.0 : 10/01/88 :
2.01 : 03/ /89 :
2.02 : 10/04/89 : Fixed probability message,
Got rid of title screen when game ends.
2.03 : 01/22/90 : Added hint for field puzzle.
: 02/05/90 : "look" without noun will finally print the current room.
*/
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "adv-def.h"
#include "parser.h"
#include "tess-def.h"
/*------------------------------------------------------------*/
/* on some PC clones (e.g. mine), scrolling the screen when printing a '\n'
with the conio.h routines (e.g. putch('\n') or cprintf('\n')) is much slower
than the stdio.h routines.
*/
nl() { putchar('\n'); }
/*----------------------------*/
/* if tty-mode, then using standard library functions for I/O, and ignore the
screen I/O functions
*/
#ifdef tty
#define cprintf printf
#define cputs printf
#define prints puts
#define clrscr()
#define clreol()
#define gotoxy(x,y)
/* if non-tty-mode, use console IO library
*/
#else
#include <conio.h>
prints( char *s )
{
cputs( s );
nl();
}
#endif
/*----------------------------*/
int get_enter()
{
int i=0, ch;
while ((ch=getchar()) != '\n')
i+=ch;
return (i);
}
/*----------------------------*/
/* enter aux. object (e.g. Give XXX to AUX)
*/
int InputNoun( char *prompt, char *noun )
{
int nn;
cprintf( prompt );
gets( noun );
nn = GetNounNum( noun );
resize_word( noun );
return( nn );
}
/*------------------------------------------------------------*/
/* Adventure dependent stuff
*/
int
print_room, /* flag for updating room after command */
curr_loc, /* current location */
curr_lev, /* current level */
level_loc [ 4 ], /* current location for diff. levels */
zap, /* flag set when game over */
/* 1=quit 2=wrong password 3=right password */
sleep_lev, /* which level player was in when sleeping */
/* flags are 0=false/haven't done, 1=true/done */
/* unless otherwise noted */
cc, /* coil status: 0=normal b1=cooled b2=magnetized */
wa, /* water alien */
ep, /* eat pills */
dr, /* dice roll counter */
af, /* audio filter inserted */
gp, /* get password */
mi, /* message: bits 0,1,2,3 = parts found */
ti, /* think idea */
kp, /* kick projector */
dc [ 3 ], /* each dice roll, dc[i]<33 */
sum /* sum = sigma( dc ) < 100 */
;
/*----------------------------*/
InitAdv()
{
int i;
for ( i=1; i<MaxObjs; i++ )
{
obj[i].loc = obj[i].init_loc;
}
level_loc[1] = 2;
level_loc[2] = 25;
level_loc[3] = 29;
curr_lev = 1;
curr_loc = level_loc [ curr_lev ];
zap = cc = wa = ep = dr = af = gp = mi = ti = kp = 0;
for ( sum=0, i=0; i<3; i++ )
sum += (dc [i] = rand() & 31);
print_room = 1;
}
/*------------------------------------------------------------*/
/* Message routines
*/
/*----------------------------*/
PrintMess( int i )
{
switch ( i )
{
case 1: prints("Nothing special happens."); break;
case 2: prints("That isn't possible."); break;
case 3: prints("Doesn't work."); break;
case 4: prints("Can't do that yet."); break;
case 5: prints("OK."); break;
case 6: prints("How?"); break;
case 7: cprintf("You have nothing to %s with.", cmd.verb ); nl(); break;
}
}
not_happen() { PrintMess( 1 ); }
not_poss() { PrintMess( 2 ); }
not_work() { PrintMess( 3 ); }
not_yet() { PrintMess( 4 ); }
ok() { PrintMess( 5 ); }
how() { PrintMess( 6 ); }
/*------------------------------------------------------------*/
/* Object routines
*/
/*----------------------------*/
int CheckObjAttr( int nn, int mask )
{
return ( obj [nn].attr & mask );
}
#define CanGetObj(i) CheckObjAttr((i),1)
#define CanLookObj(i) CheckObjAttr((i),4)
/*----------------------------*/
CarryObj( int nn )
{
obj [nn].loc = -curr_lev;
}
int CarryingObj( int nn )
{
return ( obj [nn].loc == -curr_lev );
}
/*----------------------------*/
WearObj( int nn )
{
obj [nn].loc = -curr_lev - 3;
}
int WearingObj( int nn )
{
return ( obj [nn].loc == -curr_lev-3 );
}
/*----------------------------*/
int ObjOnPlayer( int nn )
{
return ( CarryingObj(nn) || WearingObj(nn) );
}
/*----------------------------*/
DropObj( int nn )
{
obj [nn].loc = curr_loc;
}
int ObjInRoom( int nn )
{
return ( obj [nn].loc == curr_loc );
}
/*----------------------------*/
JunkObj( int nn )
{
obj [nn].loc = 0;
}
/* replace object nn with object new_nn
*/
ReplaceObj( int nn, int new_nn )
{
obj [new_nn].loc = obj [nn].loc;
obj [nn].loc = 0;
}
/*----------------------------*/
/* See if an object is accessible. This means the object is being
carried/worn, is in the same room, is a concept noun (e.g. north),
is part of the room (e.g. field), or is part of another object
(e.g. button).
*/
int ObjIsPresent( int nn )
{
if ( (nn>=o_north) && (nn<=o_invent) ) /* direction, "inventory" */
return (1); /* always available */
else if ( (nn>=o_buttons) && (nn<=o_four) ) /* buttons */
return ( ObjIsPresent(o_proj) ); /* on projector */
else if ( (nn==o_liquid) && (obj[nn].loc==-8) ) /* contained fluid */
return ( ObjIsPresent(o_bottle) ); /* in Klein bottle */
else
return ( ObjInRoom(nn) || CarryingObj(nn) || WearingObj(nn) );
}
/*------------------------------------------------------------*/
/* Room routines
*/
/*----------------------------*/
/* predicates to return check whether the player in in a certain world
*/
int InComplex( int rn )
{
return ( rn==1 || rn==2 || rn==7 || rn==8 );
}
int InMirrorWorld( int rn )
{
return ( rn==4 || (rn>=9 && rn<=13) );
}
int InMathWorld( int rn )
{
return ( rn==3 || rn==5 || (rn>=14 && rn<=17) );
}
int InSpectralWorld( int rn )
{
return ( rn==6 || (rn>=18 && rn<=22) );
}
int InDreamWorld( int rn )
{
return ( curr_lev==2 || (rn>=23 && rn<=28) || rn==35 );
}
int InBookWorld( int rn )
{
return ( curr_lev==3 || (rn>=29 && rn<=34) );
}
/*----------------------------*/
PrintCurrRoom()
{
static int stop_line=1;
int i,flag, len,currx;
char *s;
#ifndef tty
/* clear window area from previous time
*/
for ( i=stop_line; i>=1; i-- )
{
gotoxy( 1, i );
clreol();
}
#else
cprintf("------------------------------------------------------------------------------");
nl();
#endif
cprintf("You are %s.", room [ curr_loc ].name ); nl();
prints("You see around you:");
clreol();
flag=0;
currx=0;
for ( i=1; i<MaxObjs; i++ )
if (ObjInRoom(i))
{
s = obj[i].name;
len = strlen(s);
if (currx+ len + 3 > 78 ) { currx=0; nl(); clreol(); }
cprintf(" %s.", s );
currx += len+3;
flag=1;
}
if (!flag)
prints(" Nothing special.");
else
{ nl(); clreol(); }
prints("Exits:");
clreol();
flag=0;
for ( i=0; i<MaxDirs; i++ )
if ( room [curr_loc].link [i] )
{
cprintf(" %s.", obj[i+1].name );
flag=1;
}
if (!flag) cprintf(" none.");
nl();
#ifdef tty
nl();
#else
prints("------------------------------------------------------------------------------");
stop_line = wherey(); /* stop line is the line after the separator bar */
gotoxy( 1,25 );
#endif
}
/*----------------------------*/
goto_new_lev( int lev )
{
curr_lev = lev;
curr_loc = level_loc [curr_lev];
}
goto_new_loc( int rn )
{
curr_loc = rn;
level_loc [curr_lev] = curr_loc;
}
/*------------------------------------------------------------*/
/* Verb routines
*/
/*----------------------------*/
do_go()
{
int direct, new_room;
switch ( cmd.nn )
{
case o_north:
case o_east:
case o_south:
case o_west:
direct = cmd.nn - 1; /* assumes NESW = 1234 */
new_room = room [curr_loc].link [direct];
if (new_room)
{
goto_new_loc( new_room );
print_room = 1;
}
else
prints("Can't go in that direction");
break;
default:
/*
if (isdigit(cmd.noun[0]))
{
new_room = atoi( cmd.noun );
if ( (new_room>=0) && (new_room<MaxLocs) )
goto_new_loc( new_room );
else
prints("Can't go there");
}
else
*/
prints("Use a direction or the stack");
}
}
/*----------------------------*/
do_dir()
{
cmd.nn = cmd.vn;
cmd.vn = 6;
do_go();
}
/*----------------------------*/
do_inv()
{
int flag, i, len,currx;
char s[80];
prints("You are carrying:");
flag=0;
currx=0;
for ( i=1; i<MaxObjs; i++ )
if ( ObjOnPlayer(i) )
{
strcpy( s, obj[i].name );
if (WearingObj(i)) strcat( s, " (wearing)" );
len = strlen(s);
if (currx+ len + 3 > 78 ) { currx=0; nl(); }
cprintf(" %s.", s );
currx += len+3;
flag=1;
}
if (!flag)
prints(" nothing.");
else
nl();
}
/*----------------------------*/
do_get()
{
int where, attr, i, get_flag;
char s[16], *p;
if (ObjOnPlayer(cmd.nn))
prints("You already have it.");
else if (cmd.nn==o_invent) /* get everything in room */
{
for ( i=o_invent+1; i<MaxObjs; i++ )
if ( ObjInRoom(i) && CanGetObj(i) )
{
cmd.nn=i;
cprintf( "--> get %s", obj[i].name ); nl();
do_get();
}
}
else if (!CanGetObj(cmd.nn)) /* un-gettable object? */
{
if (cmd.nn==o_plant) /* alien */
prints("The being is rooted in the 4th dimension.");
else if (cmd.nn==o_group)
prints("The group has infinitely many reasons to stay where it is.");
else if (cmd.nn==o_fluid) /* fluid */
prints("It's too cold!");
else
prints("Can't get that.");
}
else /* gettable object */
{
get_flag = 1;
if (cmd.nn==o_liquid) /* 4-D liquid */
{
how();
get_flag = 0;
}
else if (cmd.nn==o_plasma) /* plasma */
{
if (!CarryingObj(o_coil) || (cc!=3)) /* not have coil or not mag. bottle */
{
prints("Too hot to handle.");
get_flag = 0;
}
else
prints( "The magnetic field of the coil contained the plasma." );
}
else if (cmd.nn==o_improb) /* improbability */
{
get_flag = 0;
cprintf("What is the probability of getting this improbability? ");
gets( s );
p = strchr( s, '.' ); /* skip past decimal point */
if (!p)
printf("Probabilites are values between 0 and 1.\n");
else
{
p++;
i = atoi( p );
if (i!=sum && i*10!=sum)
prints("Wrong.");
else
get_flag = 1;
}
}
if (get_flag)
{
CarryObj( cmd.nn );
ok();
}
}
}
/*----------------------------*/
do_drop()
{
int where, i;
if (ObjInRoom(cmd.nn))
prints("It's already here.");
else if (cmd.nn==o_improb && curr_loc==16)
do_throw();
else if (cmd.nn==o_invent) /* drop everything */
{
for ( i=o_invent+1; i<MaxObjs; i++ )
if ( ObjOnPlayer(i) )
{
cmd.nn=i;
cprintf( "--> drop %s", obj[i].name ); nl();
do_drop();
}
}
else if (cmd.nn>o_invent)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -