|
|
1.1 root 1: /* create.c Larn is copyrighted 1986 by Noah Morgan. */
2: #include "header.h"
3: extern char spelknow[],larnlevels[];
4: extern char beenhere[],wizard,level;
5: extern short oldx,oldy;
6: /*
7: makeplayer()
8:
9: subroutine to create the player and the players attributes
10: this is called at the beginning of a game and at no other time
11: */
12: makeplayer()
13: {
14: register int i;
15: scbr(); clear();
16: c[HPMAX]=c[HP]=10; /* start player off with 15 hit points */
17: c[LEVEL]=1; /* player starts at level one */
18: c[SPELLMAX]=c[SPELLS]=1; /* total # spells starts off as 3 */
19: c[REGENCOUNTER]=16; c[ECOUNTER]=96; /*start regeneration correctly*/
20: c[SHIELD] = c[WEAR] = c[WIELD] = -1;
21: for (i=0; i<26; i++) iven[i]=0;
22: spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
23: if (c[HARDGAME]<=0)
24: {
25: iven[0]=OLEATHER; iven[1]=ODAGGER;
26: ivenarg[1]=ivenarg[0]=c[WEAR]=0; c[WIELD]=1;
27: }
28: playerx=rnd(MAXX-2); playery=rnd(MAXY-2);
29: oldx=0; oldy=25;
30: gtime=0; /* time clock starts at zero */
31: cbak[SPELLS] = -50;
32: for (i=0; i<6; i++) c[i]=12; /* make the attributes, ie str, int, etc. */
33: recalc();
34: }
35:
36: /*
37: newcavelevel(level)
38: int level;
39:
40: function to enter a new level. This routine must be called anytime the
41: player changes levels. If that level is unknown it will be created.
42: A new set of monsters will be created for a new level, and existing
43: levels will get a few more monsters.
44: Note that it is here we remove genocided monsters from the present level.
45: */
46: newcavelevel(x)
47: register int x;
48: {
49: register int i,j;
50: if (beenhere[level]) savelevel(); /* put the level back into storage */
51: level = x; /* get the new level and put in working storage */
52: if (beenhere[x]==0) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=mitem[j][i]=0;
53: else { getlevel(); sethp(0); goto chgn; }
54: makemaze(x); makeobject(x); beenhere[x]=1; sethp(1);
55:
56: #if WIZID
57: if (wizard || x==0)
58: #else
59: if (x==0)
60: #endif
61:
62: for (j=0; j<MAXY; j++)
63: for (i=0; i<MAXX; i++)
64: know[i][j]=1;
65: chgn: checkgen(); /* wipe out any genocided monsters */
66: }
67:
68: /*
69: makemaze(level)
70: int level;
71:
72: subroutine to make the caverns for a given level. only walls are made.
73: */
74: static int mx,mxl,mxh,my,myl,myh,tmp2;
75: makemaze(k)
76: int k;
77: {
78: register int i,j,tmp;
79: int z;
80: if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
81: {
82: if (cannedlevel(k)); return; /* read maze from data file */
83: }
84: if (k==0) tmp=0; else tmp=OWALL;
85: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) item[j][i]=tmp;
86: if (k==0) return; eat(1,1);
87: if (k==1) item[33][MAXY-1]=0; /* exit from dungeon */
88:
89: /* now for open spaces -- not on level 10 */
90: if (k != MAXLEVEL-1)
91: {
92: tmp2 = rnd(3)+3;
93: for (tmp=0; tmp<tmp2; tmp++)
94: {
95: my = rnd(11)+2; myl = my - rnd(2); myh = my + rnd(2);
96: if (k < MAXLEVEL)
97: {
98: mx = rnd(44)+5; mxl = mx - rnd(4); mxh = mx + rnd(12)+3;
99: z=0;
100: }
101: else
102: {
103: mx = rnd(60)+3; mxl = mx - rnd(2); mxh = mx + rnd(2);
104: z = makemonst(k);
105: }
106: for (i=mxl; i<mxh; i++) for (j=myl; j<myh; j++)
107: { item[i][j]=0;
108: if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
109: }
110: }
111: }
112: if (k!=MAXLEVEL-1) { my=rnd(MAXY-2); for (i=1; i<MAXX-1; i++) item[i][my] = 0; }
113: if (k>1) treasureroom(k);
114: }
115:
116: /*
117: function to eat away a filled in maze
118: */
119: eat(xx,yy)
120: register int xx,yy;
121: {
122: register int dir,try;
123: dir = rnd(4); try=2;
124: while (try)
125: {
126: switch(dir)
127: {
128: case 1: if (xx <= 2) break; /* west */
129: if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
130: item[xx-1][yy] = item[xx-2][yy] = 0;
131: eat(xx-2,yy); break;
132:
133: case 2: if (xx >= MAXX-3) break; /* east */
134: if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
135: item[xx+1][yy] = item[xx+2][yy] = 0;
136: eat(xx+2,yy); break;
137:
138: case 3: if (yy <= 2) break; /* south */
139: if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
140: item[xx][yy-1] = item[xx][yy-2] = 0;
141: eat(xx,yy-2); break;
142:
143: case 4: if (yy >= MAXY-3 ) break; /* north */
144: if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
145: item[xx][yy+1] = item[xx][yy+2] = 0;
146: eat(xx,yy+2); break;
147: };
148: if (++dir > 4) { dir=1; --try; }
149: }
150: }
151:
152: /*
153: * function to read in a maze from a data file
154: *
155: * Format of maze data file: 1st character = # of mazes in file (ascii digit)
156: * For each maze: 18 lines (1st 17 used) 67 characters per line
157: *
158: * Special characters in maze data file:
159: *
160: * # wall D door . random monster
161: * ~ eye of larn ! cure dianthroritis
162: * - random object
163: */
164: cannedlevel(k)
165: int k;
166: {
167: char *row,*lgetl();
168: register int i,j;
169: int it,arg,mit,marg;
170: if (lopen(larnlevels)<0)
171: {
172: write(1,"Can't open the maze data file\n",30); died(-282); return(0);
173: }
174: i=lgetc(); if (i<='0') { died(-282); return(0); }
175: for (i=18*rund(i-'0'); i>0; i--) lgetl(); /* advance to desired maze */
176: for (i=0; i<MAXY; i++)
177: {
178: row = lgetl();
179: for (j=0; j<MAXX; j++)
180: {
181: it = mit = arg = marg = 0;
182: switch(*row++)
183: {
184: case '#': it = OWALL; break;
185: case 'D': it = OCLOSEDDOOR; arg = rnd(30); break;
186: case '~': if (k!=MAXLEVEL-1) break;
187: it = OLARNEYE;
188: mit = rund(8)+DEMONLORD;
189: marg = monster[mit].hitpoints; break;
190: case '!': if (k!=MAXLEVEL+MAXVLEVEL-1) break;
191: it = OPOTION; arg = 21;
192: mit = DEMONLORD+7;
193: marg = monster[mit].hitpoints; break;
194: case '.': if (k<MAXLEVEL) break;
195: mit = makemonst(k+1);
196: marg = monster[mit].hitpoints; break;
197: case '-': it = newobject(k+1,&arg); break;
198: };
199: item[j][i] = it; iarg[j][i] = arg;
200: mitem[j][i] = mit; hitp[j][i] = marg;
201:
202: #if WIZID
203: know[j][i] = (wizard) ? 1 : 0;
204: #else
205: know[j][i] = 0;
206: #endif
207: }
208: }
209: lrclose();
210: return(1);
211: }
212:
213: /*
214: function to make a treasure room on a level
215: level 10's treasure room has the eye in it and demon lords
216: level V3 has potion of cure dianthroritis and demon prince
217: */
218: treasureroom(lv)
219: register int lv;
220: {
221: register int tx,ty,xsize,ysize;
222:
223: for (tx=1+rnd(10); tx<MAXX-10; tx+=10)
224: if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
225: {
226: xsize = rnd(6)+3; ysize = rnd(3)+3;
227: ty = rnd(MAXY-9)+1; /* upper left corner of room */
228: if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
229: troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
230: else troom(lv,xsize,ysize,tx,ty,rnd(9));
231: }
232: }
233:
234: /*
235: * subroutine to create a treasure room of any size at a given location
236: * room is filled with objects and monsters
237: * the coordinate given is that of the upper left corner of the room
238: */
239: troom(lv,xsize,ysize,tx,ty,glyph)
240: int lv,xsize,ysize,tx,ty,glyph;
241: {
242: register int i,j;
243: int tp1,tp2;
244: for (j=ty-1; j<=ty+ysize; j++)
245: for (i=tx-1; i<=tx+xsize; i++) /* clear out space for room */
246: item[i][j]=0;
247: for (j=ty; j<ty+ysize; j++)
248: for (i=tx; i<tx+xsize; i++) /* now put in the walls */
249: {
250: item[i][j]=OWALL; mitem[i][j]=0;
251: }
252: for (j=ty+1; j<ty+ysize-1; j++)
253: for (i=tx+1; i<tx+xsize-1; i++) /* now clear out interior */
254: item[i][j]=0;
255:
256: switch(rnd(2)) /* locate the door on the treasure room */
257: {
258: case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
259: iarg[i][j] = glyph; /* on horizontal walls */
260: break;
261: case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
262: iarg[i][j] = glyph; /* on vertical walls */
263: break;
264: };
265:
266: tp1=playerx; tp2=playery; playery=ty+(ysize>>1);
267: if (c[HARDGAME]<2)
268: for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
269: for (i=0, j=rnd(6); i<=j; i++)
270: { something(lv+2); createmonster(makemonst(lv+1)); }
271: else
272: for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
273: for (i=0, j=rnd(4); i<=j; i++)
274: { something(lv+2); createmonster(makemonst(lv+3)); }
275:
276: playerx=tp1; playery=tp2;
277: }
278:
279: /*
280: ***********
281: MAKE_OBJECT
282: ***********
283: subroutine to create the objects in the maze for the given level
284: */
285: makeobject(j)
286: register int j;
287: {
288: register int i;
289: if (j==0)
290: {
291: fillroom(OENTRANCE,0); /* entrance to dungeon */
292: fillroom(ODNDSTORE,0); /* the DND STORE */
293: fillroom(OSCHOOL,0); /* college of Larn */
294: fillroom(OBANK,0); /* 1st national bank of larn */
295: fillroom(OVOLDOWN,0); /* volcano shaft to temple */
296: fillroom(OHOME,0); /* the players home & family */
297: fillroom(OTRADEPOST,0); /* the trading post */
298: fillroom(OLRS,0); /* the larn revenue service */
299: return;
300: }
301:
302: if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
303:
304: /* make the fixed objects in the maze STAIRS */
305: if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
306: fillroom(OSTAIRSDOWN,0);
307: if ((j > 1) && (j != MAXLEVEL)) fillroom(OSTAIRSUP,0);
308:
309: /* make the random objects in the maze */
310:
311: fillmroom(rund(3),OBOOK,j); fillmroom(rund(3),OALTAR,0);
312: fillmroom(rund(3),OSTATUE,0); fillmroom(rund(3),OPIT,0);
313: fillmroom(rund(3),OFOUNTAIN,0); fillmroom( rnd(3)-2,OIVTELETRAP,0);
314: fillmroom(rund(2),OTHRONE,0); fillmroom(rund(2),OMIRROR,0);
315: fillmroom(rund(2),OTRAPARROWIV,0); fillmroom( rnd(3)-2,OIVDARTRAP,0);
316: fillmroom(rund(3),OCOOKIE,0);
317: if (j==1) fillmroom(1,OCHEST,j);
318: else fillmroom(rund(2),OCHEST,j);
319: if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
320: fillmroom(rund(2),OIVTRAPDOOR,0);
321: if (j<=10)
322: {
323: fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
324: fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
325: fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
326: fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
327: }
328: for (i=0; i<rnd(4)+3; i++)
329: fillroom(OPOTION,newpotion()); /* make a POTION */
330: for (i=0; i<rnd(5)+3; i++)
331: fillroom(OSCROLL,newscroll()); /* make a SCROLL */
332: for (i=0; i<rnd(12)+11; i++)
333: fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
334: if (j==5) fillroom(OBANK2,0); /* branch office of the bank */
335: froom(2,ORING,0); /* a ring mail */
336: froom(1,OSTUDLEATHER,0); /* a studded leather */
337: froom(3,OSPLINT,0); /* a splint mail */
338: froom(5,OSHIELD,rund(3)); /* a shield */
339: froom(2,OBATTLEAXE,rund(3)); /* a battle axe */
340: froom(5,OLONGSWORD,rund(3)); /* a long sword */
341: froom(5,OFLAIL,rund(3)); /* a flail */
342: froom(4,OREGENRING,rund(3)); /* ring of regeneration */
343: froom(1,OPROTRING,rund(3)); /* ring of protection */
344: froom(2,OSTRRING,4); /* ring of strength + 4 */
345: froom(7,OSPEAR,rnd(5)); /* a spear */
346: froom(3,OORBOFDRAGON,0); /* orb of dragon slaying*/
347: froom(4,OSPIRITSCARAB,0); /*scarab of negate spirit*/
348: froom(4,OCUBEofUNDEAD,0); /* cube of undead control */
349: froom(2,ORINGOFEXTRA,0); /* ring of extra regen */
350: froom(3,ONOTHEFT,0); /* device of antitheft */
351: froom(2,OSWORDofSLASHING,0); /* sword of slashing */
352: if (c[BESSMANN]==0)
353: {
354: froom(4,OHAMMER,0);/*Bessman's flailing hammer*/ c[BESSMANN]=1;
355: }
356: if (c[HARDGAME]<3 || (rnd(4)==3))
357: {
358: if (j>3)
359: {
360: froom(3,OSWORD,3); /* sunsword + 3 */
361: froom(5,O2SWORD,rnd(4)); /* a two handed sword */
362: froom(3,OBELT,4); /* belt of striking */
363: froom(3,OENERGYRING,3); /* energy ring */
364: froom(4,OPLATE,5); /* platemail + 5 */
365: }
366: }
367: }
368:
369: /*
370: subroutine to fill in a number of objects of the same kind
371: */
372:
373: fillmroom(n,what,arg)
374: int n,arg;
375: char what;
376: {
377: register int i;
378: for (i=0; i<n; i++) fillroom(what,arg);
379: }
380: froom(n,itm,arg)
381: int n,arg;
382: char itm;
383: { if (rnd(151) < n) fillroom(itm,arg); }
384:
385: /*
386: subroutine to put an object into an empty room
387: * uses a random walk
388: */
389: static fillroom(what,arg)
390: int arg;
391: char what;
392: {
393: register int x,y;
394:
395: #ifdef EXTRA
396: c[FILLROOM]++;
397: #endif
398:
399: x=rnd(MAXX-2); y=rnd(MAXY-2);
400: while (item[x][y])
401: {
402:
403: #ifdef EXTRA
404: c[RANDOMWALK]++; /* count up these random walks */
405: #endif
406:
407: x += rnd(3)-2; y += rnd(3)-2;
408: if (x > MAXX-2) x=1; if (x < 1) x=MAXX-2;
409: if (y > MAXY-2) y=1; if (y < 1) y=MAXY-2;
410: }
411: item[x][y]=what; iarg[x][y]=arg;
412: }
413:
414: /*
415: subroutine to put monsters into an empty room without walls or other
416: monsters
417: */
418: fillmonst(what)
419: char what;
420: {
421: register int x,y,trys;
422: for (trys=5; trys>0; --trys) /* max # of creation attempts */
423: {
424: x=rnd(MAXX-2); y=rnd(MAXY-2);
425: if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
426: {
427: mitem[x][y] = what; know[x][y]=0;
428: hitp[x][y] = monster[what].hitpoints; return(0);
429: }
430: }
431: return(-1); /* creation failure */
432: }
433:
434: /*
435: creates an entire set of monsters for a level
436: must be done when entering a new level
437: if sethp(1) then wipe out old monsters else leave them there
438: */
439: sethp(flg)
440: int flg;
441: {
442: register int i,j;
443: if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
444: if (level==0) { c[TELEFLAG]=0; return; } /* if teleported and found level 1 then know level we are on */
445: if (flg) j = rnd(12) + 2 + (level>>1); else j = (level>>1) + 1;
446: for (i=0; i<j; i++) fillmonst(makemonst(level));
447: positionplayer();
448: }
449:
450: /*
451: * Function to destroy all genocided monsters on the present level
452: */
453: checkgen()
454: {
455: register int x,y;
456: for (y=0; y<MAXY; y++)
457: for (x=0; x<MAXX; x++)
458: if (monster[mitem[x][y]].genocided)
459: mitem[x][y]=0; /* no more monster */
460: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.