DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦4f6b4616d⟧ TextFile

    Length: 11495 (0x2ce7)
    Types: TextFile
    Names: »cvdwrf.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Crystal/cvdwrf.c« 

TextFile

/*	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);
}