|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 11495 (0x2ce7)
Types: TextFile
Names: »cvdwrf.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Crystal/cvdwrf.c«
/* cvdwrf.c
* performs dwarf-motion stuff once per turn. Considers all moving
* creatures except the adventurer to be "dwarves" in some sense,
* because their motion rules are all very similar.
* As long as they are not dead, all dwarves move about randomly in
* much the same way that adventurers do, but the dwarves are smart
* enough to skip the usual hazards -- they never go to fatal
* places.
*************************************************************************/
#include <stdio.h>
#include <string.h>
#include "cvobj.h"
#include "cvlocs.h"
#include "cvocab.h"
#include "cvorcs.h"
#include "cvmisc.h"
#include "random.h"
extern struct rtr rtrav[]; /* rug and rope travel array */
extern int maxloc; /* test for legal locs */
extern void carry(); /* pick up object */
extern void destry(); /* destroy an object (at first location) */
extern void mkill(); /* kill monster */
extern void move(); /* place an object at a location */
extern void move2(); /* place an object at a second location,
or make it unmoveable */
extern void pspeak(); /* announce a property message of an object */
extern void rspeak(); /* utter one of the random messages */
extern void putcode(); /* used in debugging */
extern int tally, tally2; /* counts of objects seen */
int
dodwarf()
{ register struct cvobj *curobj;
register struct cvtrav *curtrv;
register struct monster *cre;
register int i;
if (closing && ( (newloc - cvloc) < 31 || newloc == DEAD) ) {
rspeak(130); /* you can't get out */
newloc = loc; /* make him stay put */
if (!panic) clock2 = 15; /* if this is his first attempt */
panic = TRUE; /* remember he has paniced already */
}
/* If monsters are following, the adventurer is not allowed to back up,
* because there's a monster in the way.
*/
if (loc != newloc /* he's moving */
&& (loc - cvloc) >=62 /* he's moving inside the cave */
&& dflag >= 2 /* dwarf stuff going */
&& !FORCED(loc) ) { /* he could be coming from there */
for (cre = MINDWR; cre->dw; ++cre) {
if ( cre->dseen
&& (newloc == cre->oloc || newloc == oldloc) ) {
newloc = loc; /* prevent him */
rspeak(2); /* tell him why */
break; /* skip checking other dwarves */
} /* end if dseen */
} /* end dwarf check */
} /* end of backup loop */
loc = newloc; /* assign the possibly new place */
/* If he gets as far as the pool hall, start up the dwarf stuff. Things
* then stay quiet for a random amount of time. At some point a (fake)
* dwarf spots him, and misses him with an axe. This encounter just
* scares him, and provides the axe he will need, but never does any harm.
* At this point, the dwarves all start moving from their (hard-wired)
* starting points.
*
* Some dwarves (those awakened by a special encounter: the King, the
* dragon, the bugbear), plus all those below the throne start later at
* the time they are called for.
*
* No dwarf starts where the axe is thrown, because a dwarf who might
* otherwise start there is assigned an alternate starting point.
*
*/
if (loc != DEAD
&& (loc - cvloc) >= 62
&& !FORCED(loc) )
switch (dflag) {
auto int dtotal, attack, stick, destj;
#define MAXDEST 20
auto struct cvloc *ddest[MAXDEST];
case 0: dflag = 1; break; /* allow things to start */
case 1: if ( !HERE(IDOL) /* could start orcs? */
&& !HERE(CHAIN) /* could start bugbear? */
&& !HERE(ORB) /* could start Grendl? */
&& !HERE(CROWN) /* could start king? */
&& !HERE(SCEPT) /* could start dragon? */
&& (PCT(85) || DARK) )
break; /* Don't start in the dark unless he's sneaking
up on one of the vital encounters */
dflag = 2; /* Go into full swing now */
for ( i = 0; i < 3; ++i ) {
cre = MINDWR + RAN(MAXDWR-MINDWR+1); /* pick a real dwarf */
if (PCT(50) && saved == -1)
cre->dloc = DEAD; /* may kill it off */
} /* end of dwarf-killing loop */
for (cre = MINDWR; cre->dw; ++cre) {
if (loc == cre->dloc)
cre->dloc = DALTLC; /* start no real dwarf here */
cre->oloc = cre->dloc;
}
rspeak(3); /* Throw the axe */
move(AXE,loc);
break;
default:
/* Things are in full swing now. Move each dwarf at random, except that
* if he's seen the adventurer, he follows. Dwarves never go to locations
* outside the cave. If wandering at random, they don't back up unless
* that's the only way to go. If they don't have to move, they attack.
* Of course, dead dwarves don't do much of anything.
*/
dtotal = attack = stick = 0;
if ( PIRATE->dloc != DEAD /* Is Pirate still alive? */
&& loc != CHLOC /* But we're not at chest loc */
&& CHEST->prop < 0 /* And never saw chest */
&& tally == tally2+1) /* And that's the last one */
PIRATE->dseen = TRUE; /* Give adventurer a hand */
for (cre = orcs; cre->iloc >= 0; ++cre) {
if (cre->dloc == DEAD || cre->dloc == cvloc) continue; /*dead*/
destj = 0;
ddest[destj] = cre->oloc; /* pad the list (could back up) */
for (curtrv = cre->dloc->travel; curtrv->word != -1; ++curtrv){
if (curtrv->s) {
for ( ;curtrv->s; curtrv++) ; /* skip sequence */
continue; /* then go try the next entry */
}
i = curtrv->l;
if ( i >= 62 /* in the cave */
&& i <= maxloc /* not message or magic */
&& ((newloc = &(cvloc[i])) != cre->oloc || cre->dseen)
/* don't back up when wandering */
&& ( ! destj || newloc != ddest[destj - 1] )
&& destj < MAXDEST /* room in array */
&& newloc != cre->dloc
&& !FORCED(&(cvloc[i])) /* don't enter danger */
&& ( cre != PIRATE || !BADPLC(newloc)) ) {
ddest[destj++] = newloc; /* enter possible move */
}
} /* end of testing travel array */
i = destj; /* remember how many */
if (destj) destj = RAN(destj); else i++; /* make a selection */
cre->oloc = cre->dloc;
cre->dloc = ddest[destj];
if (loc == cre->oloc) {
cre->dloc = loc; /* pass in the hall */
destj = 0; /* flag that he's following */
} else {
for (destj = 0; destj < i; ++destj) {
if (ddest[destj] == loc) {
destj = 0; /* flag that he could follow */
break;
}
}
}
#ifdef DEBUG
if (cre == BALLY) {
printf("\nBALLY to loc %d: ",cre->dloc - cvloc);
putcode(cre->dloc->ldesc);
putchar('\n');
}
#endif
if ( loc == cre->dloc /* it's here, or */
|| (cre->dseen /* it's following, and */
&& ((destj < i) /* it could follow (priest special ) */
|| ( cre == PRIEST && LNUM(loc) == 134 ) ) ) ) {
cre->dloc = loc;
cre->dseen = TRUE;
switch (cre - orcs) {
case IPIRAT:
#ifdef DEBUG
puts("\nThe pirate is here.");
#endif
if (loc == CHLOC || FOUND(CHEST)) break;
for (i = 0, curobj = MINTRS;
curobj != ENDTRS; ++curobj) {
if (TOTING(curobj)) break;
if (HERE(curobj)) i=1;
}
if (curobj == ENDTRS) {
/* nothing to steal, but we'll hear from him anyway */
if (tally == (tally2 + 1)
&& i == 0
&& CHEST->conn1.where == LOST
&& HERE(LAMP)
&& LAMP->prop == 0 ) {
rspeak(186);
move(CHEST,CHLOC);
} else {
if (cre->oloc != cre->dloc
&& PCT(20))
rspeak(127);
break;
}
} else { /* he's gonna get something */
rspeak(128);
if (CHEST->conn1.where == LOST)
move(CHEST,CHLOC);
for (curobj = MINTRS; curobj != ENDTRS; ++curobj) {
if (HERE(curobj)) {
if (curobj == ORB && INMAZE(loc)) {
if (LNUM(loc) != 92
&& curobj->conn2.where == LOST)
move(curobj,&(cvloc[92]));
} else {
if (curobj->conn2.where == LOST)
move(curobj,CHLOC);
}
} /* end handling toted treasure */
} /* end of stealing loop */
PIRATE->dloc = PIRATE->oloc = CHLOC;
PIRATE->dseen = FALSE;
} /* end of any-treasure-here case */
/* end of the pirate's wickedness (for now) */
break; /* switch break */
case IGRENDL:
pspeak(SPIDER,1); /* he's after you */
if (PCT(50)) break; /* half the time he does no more */
if (TOTING(SWORD)) {
rspeak(137); /* sorry about that, Grendl */
mkill(&(orcs[IGRENDL]),SPIDER);
} else {
rspeak(135);
oldlc2 = loc;
goto dead;
}
break;
case IDRAGON:
pspeak(DRAGON,2+RAN(8)); /* just keep bitchin' */
break;
case IKING:
pspeak(HELM,1); /* he's after you! */
if (cre->dloc == PUFF->dloc) {
pspeak(HELM,3); /* can't stand complaints */
mkill(PUFF,DRAGON);
} else {
if (( loc == oldloc || loc == oldlc2) && PCT(40)) {
pspeak(HELM,5); /* sorry 'bout that */
oldlc2 = loc;
goto dead;
}
}
break;
case IDJINN:
pspeak(DJINN,0); /* he's here */
break;
case IKOBOLD:
pspeak(KOBOLD,0); /* he's here */
if (( loc == oldloc || loc == oldlc2) && PCT(25)) {
pspeak(KOBOLD,2);
oldlc2 = loc;
goto dead;
} else {
pspeak(KOBOLD,1);
}
break;
case IBEAR:
move(BEAR,loc);
if (( loc == oldloc || loc == oldlc2) && PCT(25)) {
rspeak(196);
oldlc2 = loc;
goto dead;
}
break;
case IUNICRN:
move(UNICRN,loc);
break;
case IPRIEST:
move(GIANT,loc);
if (( loc == oldloc || loc == oldlc2) && PCT(50)) {
rspeak(223);
oldlc2 = loc;
goto dead;
} else {
if (LNUM(loc) == 134) {
pspeak(GIANT,4); /* bye, bye priest */
mkill(PRIEST,GIANT);
}
}
break;
case IBALROG:
pspeak(BALROG,2);
if (PCT(50)) {
pspeak(BALROG,3);
if (( loc == oldloc || loc == oldlc2 )==PCT(85)
&& RAN(limit+2) >= 10 ) {
pspeak(BALROG,4);
limit = (limit+9)/10;
}
}
break;
case ISELF:
pspeak(SELF,0);
if (PCT(17)) pspeak(SELF,RAN(3)+2);
break;
default: /* normal dwarves are the rest */
if (!cre->dw) break; /* in case I goofed */
++dtotal; /* count him in the room */
if (cre->dloc == cre->oloc) { /* if he can */
++attack;
if (knfloc != FIXED) knfloc = loc;
if (PCT((dflag-2)*5)) ++stick;
}
} /* end of switch */
} /* end of processing for being followed */
else {
#ifdef DEBUG
if (cre->dseen) {
printf("Creature %d cannot follow.\n", cre - orcs);
}
#endif
cre->dseen = FALSE;
switch (cre - orcs) {
case IBEAR:
destry(BEAR);
if (AXE->prop == 1 && AXE->conn2.where == FIXED) {
AXE->prop = 0;
AXE->conn2.where = NULL;
}
break;
case IPRIEST:
destry(GIANT);
break;
case IUNICRN:
if (UNICRN->prop != -1) UNICRN->prop = 2;
destry(UNICRN);
break;
}
}
} /* end of creature scan */
if (dtotal) {
if (dtotal > 1) {
(void) printf(
"\nThere are %d threatening little dwarves in the room with you.\n",dtotal);
} else rspeak(4);
if (attack) {
if (dflag == 2) ++dflag; /* After the first time */
if (saved != -1) dflag = 20;/* Catch copyists */
blklin = FALSE;
if (attack > 1) {
(void) printf(
"%d of them throw knives at you!\n",attack);
i = 6;
} else {
rspeak(5);
i = 52;
}
if (stick <= 1)
rspeak(i+stick);
else (void) printf(
"%d of them get you!\n",stick);
if (stick) {
oldlc2 = loc;
goto dead;
}
}
}
} /* end of switch for dwarf state */
return (FALSE);
dead: return(TRUE);
}