Hack Sources (Part 12 of 15)
ron at vaxnix.UUCP
ron at vaxnix.UUCP
Mon Dec 31 03:28:00 AEST 1984
# This is part 12 (of 15) of the Hack sources. Send complaints to
# mcvax!play .
# This is a shell archive. Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file". (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# hack.track.c hack.trap.c hack.tty.c hack.u_init.c hack.vault.c hack.version.c
echo x - hack.track.c
cat > "hack.track.c" << '//E*O*F hack.track.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#ifdef TRACK
#define UTSZ 50
coord utrack[UTSZ];
int utcnt = 0;
int utpnt = 0;
initrack(){
utcnt = utpnt = 0;
}
/* add to track */
settrack(){
if(utcnt < UTSZ) utcnt++;
if(utpnt == UTSZ) utpnt = 0;
utrack[utpnt].x = u.ux;
utrack[utpnt].y = u.uy;
utpnt++;
}
coord *
gettrack(x,y) register x,y; {
register int i,cnt;
coord tc;
cnt = utcnt;
for(i = utpnt-1; cnt--; i--){
if(i == -1) i = UTSZ-1;
tc = utrack[i];
if((x-tc.x)*(x-tc.x) + (y-tc.y)*(y-tc.y) < 3)
return(&(utrack[i]));
}
return(0);
}
#endif TRACK
//E*O*F hack.track.c//
echo x - hack.trap.c
cat > "hack.trap.c" << '//E*O*F hack.trap.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#include "def.trap.h"
extern struct monst *makemon();
char vowels[] = "aeiou";
char *traps[] = {
" bear trap",
"n arrow trap",
" dart trap",
" trapdoor",
" teleportation trap",
" pit",
" sleeping gas trap",
" piercer",
" mimic"
};
dotrap(trap) register struct gen *trap; {
nomul(0);
if(trap->gflag&SEEN && !rn2(5))
pline("You escape a%s.",traps[trap->gflag&037]);
else {
trap->gflag |= SEEN;
switch(trap->gflag & ~SEEN) {
case SLP_GAS_TRAP:
pline("A cloud of gas puts you to sleep!");
nomul(-rnd(25));
break;
case BEAR_TRAP:
if(Levitation) {
pline("You float over a bear trap.");
break;
}
u.utrap = 4 + rn2(4);
u.utraptype = TT_BEARTRAP;
pline("A bear trap closes on your foot!");
break;
case PIERC:
deltrap(trap);
if(makemon(PM_PIERC,u.ux,u.uy)) {
pline("A piercer suddenly drops from the ceiling!");
if(uarmh)
pline("Its blow glances off your helmet.");
else
(void) thitu(3,d(4,6),"falling piercer");
}
break;
case ARROW_TRAP:
pline("An arrow shoots out at you!");
if(!thitu(8,rnd(6),"arrow")){
mksobj_at(WEAPON_SYM, ARROW, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TRAPDOOR:
if(!xdnstair) {
pline("A trap door in the ceiling opens and a rock falls on your head!");
if(uarmh) pline("Fortunately, you are wearing a helmet!");
losehp(uarmh ? 2 : d(2,10),"falling rock");
} else {
register int newlevel = dlevel + 1;
while(!rn2(4) && newlevel < 29)
newlevel++;
pline("A trap door opens up under you!");
if(Levitation || u.ustuck) {
pline("For some reason you don't fall in.");
break;
}
goto_level(newlevel, FALSE);
}
break;
case DART_TRAP:
pline("A little dart shoots out at you!");
if(thitu(7,rnd(3),"little dart")) {
if(!rn2(6))
poisoned("dart","poison dart");
} else {
mksobj_at(WEAPON_SYM, DART, u.ux, u.uy);
fobj->quan = 1;
}
break;
case TELEP_TRAP:
newsym(u.ux,u.uy);
tele();
break;
case PIT:
if(Levitation) {
pline("A pit opens up under you!");
pline("You don't fall in!");
break;
}
pline("You fall into a pit!");
u.utrap = rn1(6,2);
u.utraptype = TT_PIT;
losehp(rnd(6),"fall into a pit");
selftouch("Falling, you");
break;
default:
pline("You hit a trap of type %d",trap->gflag);
impossible();
}
}
}
mintrap(mtmp) register struct monst *mtmp; {
register struct gen *gen = g_at(mtmp->mx, mtmp->my, ftrap);
register int wasintrap = mtmp->mtrapped;
if(!gen) {
mtmp->mtrapped = 0; /* perhaps teleported? */
} else if(wasintrap) {
if(!rn2(40)) mtmp->mtrapped = 0;
} else {
register int tt = (gen->gflag & ~SEEN);
int in_sight = cansee(mtmp->mx,mtmp->my);
extern char mlarge[];
if(mtmp->mtrapseen & (1 << tt)) {
/* he has been in such a trap - perhaps he escapes */
if(rn2(4)) return(0);
}
mtmp->mtrapseen |= (1 << tt);
switch (tt) {
case BEAR_TRAP:
if(index(mlarge, mtmp->data->mlet)) {
if(in_sight)
pline("%s is caught in a bear trap!",
Monnam(mtmp));
else
if(mtmp->data->mlet == 'o')
pline("You hear the roaring of an angry bear!");
mtmp->mtrapped = 1;
}
break;
case PIT:
if(!index("Eyw", mtmp->data->mlet)) {
mtmp->mtrapped = 1;
if(in_sight)
pline("%s falls in a pit!", Monnam(mtmp));
}
break;
case SLP_GAS_TRAP:
if(!mtmp->msleep && !mtmp->mfroz) {
mtmp->msleep = 1;
if(in_sight)
pline("%s suddenly falls asleep!",
Monnam(mtmp));
}
break;
case TELEP_TRAP:
rloc(mtmp);
if(in_sight && !cansee(mtmp->mx,mtmp->my))
pline("%s suddenly disappears!",
Monnam(mtmp));
break;
case ARROW_TRAP:
if(in_sight) {
pline("%s is hit by an arrow!",
Monnam(mtmp));
}
mtmp->mhp -= 3;
break;
case DART_TRAP:
if(in_sight) {
pline("%s is hit by a dart!",
Monnam(mtmp));
}
mtmp->mhp -= 2;
/* not mondied here !! */
break;
case TRAPDOOR:
if(!xdnstair) {
mtmp->mhp -= 10;
if(in_sight)
pline("A trap door in the ceiling opens and a rock hits %s!", monnam(mtmp));
break;
}
if(mtmp->data->mlet != 'w'){
fall_down(mtmp);
if(in_sight)
pline("Suddenly, %s disappears out of sight.", monnam(mtmp));
return(2); /* no longer on this level */
}
break;
case PIERC:
break;
default:
pline("Some monster encountered an impossible trap.");
impossible();
}
}
return(mtmp->mtrapped);
}
selftouch(arg) char *arg; {
if(uwep && uwep->otyp == DEAD_COCKATRICE){
pline("%s touch the dead cockatrice.", arg);
pline("You turn to stone.");
killer = objects[uwep->otyp].oc_name;
done("died");
}
}
float_up(){
if(u.utrap) {
if(u.utraptype == TT_PIT) {
u.utrap = 0;
pline("You float up, out of the pit!");
} else {
pline("You float up, only your leg is still stuck.");
}
} else
pline("You start to float in the air!");
}
float_down(){
register struct gen *trap;
pline("You float gently to the ground.");
if(trap = g_at(u.ux,u.uy,ftrap))
switch(trap->gflag & 037) {
case PIERC:
break;
case TRAPDOOR:
if(!xdnstair || u.ustuck) break;
/* fall into next case */
default:
dotrap(trap);
}
pickup();
}
tele()
{
extern coord getpos();
coord cc;
register int nux,nuy;
if(Teleport_control) {
pline("To what position do you want to be teleported?");
cc = getpos(1, "the desired position"); /* 1: force valid */
/* possible extensions: introduce a small error if
magic power is low; allow transfer to solid rock */
if(teleok(cc.x, cc.y)){
nux = cc.x;
nuy = cc.y;
goto gotpos;
}
pline("Sorry ...");
}
do {
nux = rnd(COLNO-1);
nuy = rn2(ROWNO);
} while(!teleok(nux, nuy));
gotpos:
if(Punished) unplacebc();
unsee();
u.utrap = 0;
u.ustuck = 0;
u.ux = nux;
u.uy = nuy;
setsee();
if(Punished) placebc(1);
if(u.uswallow){
u.uswldtim = u.uswallow = 0;
docrt();
}
nomul(0);
(void) inshop();
pickup();
if(!Blind) read_engr_at(u.ux,u.uy);
}
teleok(x,y) register int x,y; {
return( isok(x,y) && levl[x][y].typ > DOOR && !m_at(x,y) &&
!sobj_at(ENORMOUS_ROCK,x,y) && !g_at(x,y,ftrap)
);
/* Note: gold is permitted (because of vaults) */
}
placebc(attach) int attach; {
if(!uchain || !uball){
pline("Where are your chain and ball??");
impossible();
return;
}
uball->ox = uchain->ox = u.ux;
uball->oy = uchain->oy = u.uy;
if(attach){
uchain->nobj = fobj;
fobj = uchain;
if(!carried(uball)){
uball->nobj = fobj;
fobj = uball;
}
}
}
unplacebc(){
if(!carried(uball)){
freeobj(uball);
unpobj(uball);
}
freeobj(uchain);
unpobj(uchain);
}
level_tele() {
register int newlevel = 5 + rn2(20); /* 5 - 24 */
if(dlevel == newlevel)
if(!xdnstair) newlevel--; else newlevel++;
goto_level(newlevel, FALSE);
}
//E*O*F hack.trap.c//
echo x - hack.tty.c
cat > "hack.tty.c" << '//E*O*F hack.tty.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#include <stdio.h>
#include <sgtty.h>
struct sgttyb inittyb, curttyb;
extern short ospeed;
gettty(){
(void) gtty(0, &inittyb);
(void) gtty(0, &curttyb);
ospeed = inittyb.sg_ospeed;
/*
if(ospeed <= B300) flags.oneline = 1;
*/
getioctls();
xtabs();
}
/* reset terminal to original state */
settty(s) char *s; {
clear_screen();
if(s) printf(s);
(void) fflush(stdout);
if(stty(0, &inittyb) == -1) puts("Cannot change tty");
flags.echo = (inittyb.sg_flags & ECHO) ? ON : OFF;
flags.cbreak = (inittyb.sg_flags & CBREAK) ? ON : OFF;
setioctls();
}
setctty(){
if(stty(0, &curttyb) == -1) puts("Cannot change tty");
}
setftty(){
register int ef = (flags.echo == ON) ? ECHO : 0;
register int cf = (flags.cbreak == ON) ? CBREAK : 0;
register int change = 0;
if((curttyb.sg_flags & ECHO) != ef){
curttyb.sg_flags &= ~ECHO;
curttyb.sg_flags |= ef;
change++;
}
if((curttyb.sg_flags & CBREAK) != cf){
curttyb.sg_flags &= ~CBREAK;
curttyb.sg_flags |= cf;
change++;
}
if(change){
setctty();
}
}
echo(n)
register n;
{
/* (void) gtty(0,&curttyb); */
if(n == ON)
curttyb.sg_flags |= ECHO;
else
curttyb.sg_flags &= ~ECHO;
setctty();
}
/* always want to expand tabs, or to send a clear line char before
printing something on topline */
xtabs()
{
/* (void) gtty(0, &curttyb); */
curttyb.sg_flags |= XTABS;
setctty();
}
#ifdef LONG_CMD
cbreak(n)
register n;
{
/* (void) gtty(0,&curttyb); */
if(n == ON)
curttyb.sg_flags |= CBREAK;
else
curttyb.sg_flags &= ~CBREAK;
setctty();
}
#endif LONG_CMD
getlin(bufp)
register char *bufp;
{
register char *obufp = bufp;
register int c;
flags.topl = 2; /* nonempty, no --More-- required */
for(;;) {
(void) fflush(stdout);
if((c = getchar()) == EOF) {
*bufp = 0;
return;
}
if(c == '\b') {
if(bufp != obufp) {
bufp--;
putstr("\b \b"); /* putsym converts \b */
} else bell();
} else if(c == '\n') {
*bufp = 0;
return;
} else {
*bufp = c;
bufp[1] = 0;
putstr(bufp);
if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO)
bufp++;
}
}
}
getret() {
xgetret(TRUE);
}
cgetret() {
xgetret(FALSE);
}
xgetret(spaceflag)
boolean spaceflag; /* TRUE if space (return) required */
{
printf("\nHit %s to continue: ",
flags.cbreak ? "space" : "return");
xwaitforspace(spaceflag);
}
char morc; /* tell the outside world what char he used */
xwaitforspace(spaceflag)
boolean spaceflag;
{
register int c;
(void) fflush(stdout);
morc = 0;
while((c = getchar()) != '\n') {
if(c == EOF) {
settty("End of input?\n");
exit(0);
}
if(flags.cbreak) {
if(c == ' ') break;
if(!spaceflag && letter(c)) {
morc = c;
break;
}
}
}
}
char *
parse()
{
static char inline[COLNO];
register foo;
flags.move = 1;
if(!Invis) curs(u.ux,u.uy+2); else home();
(void) fflush(stdout);
while((foo = getchar()) >= '0' && foo <= '9')
multi += 10*multi+foo-'0';
if(multi) {
multi--;
save_cm = inline;
}
inline[0] = foo;
inline[1] = 0;
if(foo == EOF) {
settty("End of input?\n");
exit(0);
}
if(foo == 'f' || foo == 'F'){
inline[1] = getchar();
#ifdef QUEST
if(inline[1] == foo) inline[2] = getchar(); else
#endif QUEST
inline[2] = 0;
}
if(foo == 'm' || foo == 'M'){
inline[1] = getchar();
inline[2] = 0;
}
clrlin();
return(inline);
}
char
readchar() {
register int sym;
(void) fflush(stdout);
if((sym = getchar()) == EOF) {
settty("End of input?\n");
exit(0);
}
if(flags.topl == 1) flags.topl = 2;
return((char) sym);
}
//E*O*F hack.tty.c//
echo x - hack.u_init.c
cat > "hack.u_init.c" << '//E*O*F hack.u_init.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#include <stdio.h>
#include <signal.h>
#define Strcat (void) strcat
#define UNDEF_TYP 0
#define UNDEF_SPE (-1)
extern struct obj *addinv();
extern char plname[];
char pl_character[PL_CSIZ];
struct trobj {
uchar trotyp;
schar trspe;
char trolet;
Bitfield(trquan,6);
Bitfield(trknown,1);
};
#ifdef WIZARD
struct trobj Extra_objs[] = {
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 }
};
#endif WIZARD
struct trobj Cave_man[] = {
{ MACE, 1, WEAPON_SYM, 1, 1 },
{ BOW, 1, WEAPON_SYM, 1, 1 },
{ ARROW, 0, WEAPON_SYM, 25, 1 }, /* quan is variable */
{ LEATHER_ARMOR, 2, ARMOR_SYM, 1, 1 },
{ 0, 0, 0, 0, 0}
};
struct trobj Fighter[] = {
{ TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
{ RING_MAIL, 3, ARMOR_SYM, 1, 1 },
{ 0, 0, 0, 0, 0 }
};
struct trobj Knight[] = {
{ LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
{ SPEAR, 2, WEAPON_SYM, 1, 1 },
{ RING_MAIL, 4, ARMOR_SYM, 1, 1 },
{ HELMET, 1, ARMOR_SYM, 1, 1 },
{ SHIELD, 1, ARMOR_SYM, 1, 1 },
{ PAIR_OF_GLOVES, 1, ARMOR_SYM, 1, 1 },
{ 0, 0, 0, 0, 0 }
};
struct trobj Speleologist[] = {
{ STUDDED_LEATHER_ARMOR, 3, ARMOR_SYM, 1, 1 },
{ UNDEF_TYP, 0, POTION_SYM, 2, 0 },
{ FOOD_RATION, 0, FOOD_SYM, 3, 1 },
{ ICE_BOX, 0, TOOL_SYM, 1, 0 },
{ 0, 0, 0, 0, 0}
};
struct trobj Tourist[] = {
{ UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
{ POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
{ EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
{ DART, 2, WEAPON_SYM, 25, 1 }, /* quan is variable */
{ 0, 0, 0, 0, 0 }
};
struct trobj Wizard[] = {
{ ELVEN_CLOAK, 1, ARMOR_SYM, 1, 1 },
{ UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
{ UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
{ UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
{ UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
{ 0, 0, 0, 0, 0 }
};
#ifdef NEWS
int u_in_infl;
u_in_intrup(){
u_in_infl++;
(void) signal(SIGINT, u_in_intrup);
}
#endif NEWS
u_init(){
register int c,pc,i;
#ifdef NEWS
/* It is not unlikely that we get an interrupt here
intended to kill the news; unfortunately this would
also kill (part of) the following question */
int (*prevsig)() = signal(SIGINT, u_in_intrup);
#endif NEWS
register char *cp;
char buf[256];
if(pc = pl_character[0]) goto got_suffix;
buf[0] = 0;
Strcat(buf, "\nTell me what kind of character you are:\n");
Strcat(buf, "Are you a Tourist, a Speleologist, a Fighter,\n");
Strcat(buf, "\ta Knight, a Cave-man or a Wizard? [TSFKCW] ");
intrup:
for(cp = buf; *cp; cp++){
#ifdef NEWS
if(u_in_infl){
u_in_infl = 0;
goto intrup;
}
#endif NEWS
(void) putchar(*cp);
}
loop:
(void) fflush(stdout);
pc = 0;
while((c = getchar()) != '\n') {
if(c == EOF) {
#ifdef NEWS
if(u_in_infl) goto intrup; /* %% */
#endif NEWS
settty("\nEnd of input?\n");
exit(0);
}
if(!pc) pc = c;
}
if(!pc || !index("TSFKCWtsfkcw", pc)){
printf("Answer with T,S,F,K,C or W. What are you? ");
goto loop;
}
got_suffix:
if('a' <= pc && pc <= 'z') pc += 'A'-'a';
#ifdef NEWS
(void) signal(SIGINT,prevsig);
#endif NEWS
u.usym = '@';
u.ulevel = 1;
init_uhunger();
u.uhpmax = u.uhp = 12;
u.ustrmax = u.ustr = !rn2(20) ? 14 + rn2(7) : 16;
#ifdef QUEST
u.uhorizon = 6;
#endif QUEST
switch(pc) {
case 'C':
setpl_char("Cave-man");
Cave_man[2].trquan = 12 + rnd(9)*rnd(9);
u.uhp = u.uhpmax = 16;
u.ustr = u.ustrmax = 18;
ini_inv(Cave_man);
break;
case 'T':
setpl_char("Tourist");
Tourist[3].trquan = 20 + rnd(20);
u.ugold = u.ugold0 = rnd(1000);
u.uhp = u.uhpmax = 10;
u.ustr = u.ustrmax = 8;
ini_inv(Tourist);
break;
case 'W':
setpl_char("Wizard");
for(i=1; i<=4; i++) if(!rn2(5))
Wizard[i].trquan += rn2(3) - 1;
u.uhp = u.uhpmax = 15;
u.ustr = u.ustrmax = 16;
ini_inv(Wizard);
break;
case 'S':
setpl_char("Speleologist");
Fast = INTRINSIC;
Stealth = INTRINSIC;
u.uhp = u.uhpmax = 12;
u.ustr = u.ustrmax = 10;
ini_inv(Speleologist);
break;
case 'K':
setpl_char("Knight");
u.uhp = u.uhpmax = 12;
u.ustr = u.ustrmax = 10;
ini_inv(Knight);
break;
case 'F':
setpl_char("Fighter");
u.uhp = u.uhpmax = 14;
u.ustr = u.ustrmax = 17;
ini_inv(Fighter);
}
find_ac();
/* make sure he can carry all he has - especially for T's */
while(inv_weight() > 0 && u.ustr < 118)
u.ustr++, u.ustrmax++;
#ifdef WIZARD
if(wizard) wiz_inv();
#endif WIZARD
}
ini_inv(trop) register struct trobj *trop; {
register struct obj *obj;
extern struct obj *mkobj();
while(trop->trolet) {
obj = mkobj(trop->trolet);
obj->known = trop->trknown;
obj->cursed = 0;
if(obj->olet == WEAPON_SYM){
obj->quan = trop->trquan;
trop->trquan = 1;
}
if(trop->trspe != UNDEF_SPE)
obj->spe = trop->trspe;
if(trop->trotyp != UNDEF_TYP)
obj->otyp = trop->trotyp;
obj->owt = weight(obj); /* defined after setting otyp+quan */
obj = addinv(obj);
if(obj->olet == ARMOR_SYM){
switch(obj->otyp){
case SHIELD:
if(!uarms) setworn(obj, W_ARMS);
break;
case HELMET:
if(!uarmh) setworn(obj, W_ARMH);
break;
case PAIR_OF_GLOVES:
if(!uarmg) setworn(obj, W_ARMG);
break;
case ELVEN_CLOAK:
if(!uarm2)
setworn(obj, W_ARM);
break;
default:
if(!uarm) setworn(obj, W_ARM);
}
}
if(obj->olet == WEAPON_SYM)
if(!uwep) setuwep(obj);
if(--trop->trquan) continue; /* make a similar object */
trop++;
}
}
#ifdef WIZARD
wiz_inv(){
register struct trobj *trop = &Extra_objs[0];
extern char *getenv();
register char *ep = getenv("INVENT");
register int type;
while(ep && *ep) {
type = atoi(ep);
ep = index(ep, ',');
if(ep) while(*ep == ',' || *ep == ' ') ep++;
if(type <= 0 || type > NROFOBJECTS) continue;
trop->trotyp = type;
trop->trolet = objects[type].oc_olet;
trop->trspe = 4;
trop->trknown = 1;
trop->trquan = 1;
ini_inv(trop);
}
/* give him a wand of wishing by default */
trop->trotyp = WAN_WISHING;
trop->trolet = WAND_SYM;
trop->trspe = 20;
trop->trknown = 1;
trop->trquan = 1;
ini_inv(trop);
}
#endif WIZARD
setpl_char(plc) char *plc; {
(void) strncpy(pl_character, plc, PL_CSIZ-1);
pl_character[PL_CSIZ-1] = 0;
}
plnamesuffix() {
register char *p;
if(p = rindex(plname, '-')) {
*p = 0;
if(!plname[0]) {
askname();
plnamesuffix();
}
if(index("TSFKCWtsfkcw", p[1])) {
pl_character[0] = p[1];
pl_character[1] = 0;
}
}
}
//E*O*F hack.u_init.c//
echo x - hack.vault.c
cat > "hack.vault.c" << '//E*O*F hack.vault.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "hack.h"
#ifdef QUEST
setgd(/* mtmp */) /* struct monst *mtmp; */ {}
gd_move() { return(2); }
gddead(mtmp) struct monst *mtmp; {}
invault(){}
#else
extern struct monst *makemon();
#define VAULT 6
#define FCSIZ (ROWNO+COLNO)
struct fakecorr {
xchar fx,fy,ftyp;
};
struct egd {
int fcbeg, fcend; /* fcend: first unused pos */
xchar gdx, gdy; /* goal of guard's walk */
unsigned gddone:1;
struct fakecorr fakecorr[FCSIZ];
};
struct permonst pm_guard =
{ "guard", '@', 12, 12, -1, 4, 10, sizeof(struct egd) };
struct monst *guard;
int gdlevel;
#define EGD ((struct egd *)(&(guard->mextra[0])))
restfakecorr(){
register fcx,fcy,fcbeg;
register struct rm *crm;
while((fcbeg = EGD->fcbeg) < EGD->fcend) {
fcx = EGD->fakecorr[fcbeg].fx;
fcy = EGD->fakecorr[fcbeg].fy;
if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) ||
m_at(fcx,fcy))
return;
crm = &levl[fcx][fcy];
crm->typ = EGD->fakecorr[fcbeg].ftyp;
if(!crm->typ) crm->seen = 0;
newsym(fcx,fcy);
EGD->fcbeg++;
}
/* it seems he left the corridor - let the guard disappear */
mondead(guard);
guard = 0;
}
setgd(){
register struct monst *mtmp;
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){
guard = mtmp;
gdlevel = dlevel;
return;
}
guard = 0;
}
invault(){
register tmp = inroom(u.ux, u.uy);
if(tmp < 0 || rooms[tmp].rtype != VAULT) {
u.uinvault = 0;
return;
}
if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) {
char buf[BUFSZ];
register x,y,dx,dy,gx,gy;
/* first find the goal for the guard */
for(dy = 0; dy < ROWNO; dy++)
for(y = u.uy-dy; y <= u.uy+dy; y++) {
if(y > u.uy-dy) y = u.uy+dy;
if(y < 0 || y > ROWNO-1) continue;
for(x = u.ux; x < COLNO; x++)
if(levl[x][y].typ == CORR) goto fnd;
for(x = u.ux-1; x > 0; x--)
if(levl[x][y].typ == CORR) goto fnd;
}
impossible();
tele();
return;
fnd:
gx = x; gy = y;
/* next find a good place for a door in the wall */
x = u.ux; y = u.uy;
while(levl[x][y].typ > DOOR) {
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if(abs(gx-x) >= abs(gy-y)) x += dx;
else y += dy;
}
/* make something interesting happen */
if(!(guard = makemon(&pm_guard,x,y))) return;
guard->isgd = guard->mpeaceful = 1;
EGD->gddone = 0;
gdlevel = dlevel;
if(!cansee(guard->mx, guard->my)) {
mondead(guard);
guard = 0;
return;
}
EGD->gdx = gx;
EGD->gdy = gy;
EGD->fcbeg = 0;
EGD->fakecorr[0].fx = x;
EGD->fakecorr[0].fy = y;
EGD->fakecorr[0].ftyp = levl[x][y].typ;
levl[x][y].typ = DOOR;
EGD->fcend = 1;
pline("Suddenly one of the Vault's guards enters!");
pmon(guard);
pline("\"Hello stranger, who are you?\" - ");
getlin(buf);
clrlin();
pline("\"I don't know you.\"");
if(!u.ugold) pline("\"Please follow me.\"");
else {
pline("\"Most likely all that gold was stolen from this vault.\"");
pline("\"Please drop your gold (say d$ ) and follow me.\"");
}
}
}
gd_move(){
register int x,y,dx,dy,gx,gy,nx,ny,tmp;
register struct fakecorr *fcp;
register struct rm *crm;
if(!guard || gdlevel != dlevel){
pline("Where is the guard?");
impossible();
return(2); /* died */
}
if(u.ugold || dist(guard->mx,guard->my) > 2 || EGD->gddone){
restfakecorr();
return(0); /* didnt move */
}
x = guard->mx;
y = guard->my;
/* look around (hor & vert only) for accessible places */
for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
if(nx == x || ny == y) if(nx != x || ny != y)
if(isok(nx,ny))
if((tmp = (crm = &levl[nx][ny])->typ) >= SDOOR) {
register int i;
for(i = EGD->fcbeg; i < EGD->fcend; i++)
if(EGD->fakecorr[i].fx == nx &&
EGD->fakecorr[i].fy == ny)
goto nextnxy;
if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT)
goto nextnxy;
/* seems we found a good place to leave him alone */
EGD->gddone = 1;
if(tmp >= DOOR) goto newpos;
crm->typ = (tmp == SCORR) ? CORR : DOOR;
goto proceed;
nextnxy: ;
}
nx = x;
ny = y;
gx = EGD->gdx;
gy = EGD->gdy;
dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
while((tmp = (crm = &levl[nx][ny])->typ) != 0) {
/* in view of the above we must have tmp < SDOOR */
/* must be a wall here */
if(isok(nx+nx-x,ny+ny-y) && levl[nx+nx-x][ny+ny-y].typ > DOOR){
crm->typ = DOOR;
goto proceed;
}
if(dy && nx != x) {
nx = x; ny = y+dy; dx = 0;
continue;
}
if(dx && ny != y) {
ny = y; nx = x+dx; dy = 0;
continue;
}
/* I don't like this, but ... */
crm->typ = DOOR;
goto proceed;
}
crm->typ = CORR;
proceed:
fcp = &(EGD->fakecorr[EGD->fcend]);
if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow");
fcp->fx = nx;
fcp->fy = ny;
fcp->ftyp = tmp;
newpos:
if(EGD->gddone) nx = ny = 0;
guard->mx = nx;
guard->my = ny;
pmon(guard);
restfakecorr();
return(1);
}
gddead(){
guard = 0;
}
#endif QUEST
//E*O*F hack.vault.c//
echo x - hack.version.c
cat > "hack.version.c" << '//E*O*F hack.version.c//'
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
#include "date.h"
doversion(){
pline("%s 1.0 preliminary version - last edit %s.",
#ifdef QUEST
"Quest"
#else
"Hack"
#endif QUEST
, datestring);
return(0);
}
//E*O*F hack.version.c//
exit 0
More information about the Comp.sources.unix
mailing list