|
|
1.1 ! root 1: /* display.c Larn is copyrighted 1986 by Noah Morgan. */ ! 2: #include "header.h" ! 3: #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c)) ! 4: ! 5: static int minx,maxx,miny,maxy,k,m; ! 6: static char bot1f=0,bot2f=0,bot3f=0; ! 7: char always=0; ! 8: /* ! 9: bottomline() ! 10: ! 11: now for the bottom line of the display ! 12: */ ! 13: bottomline() ! 14: { recalc(); bot1f=1; } ! 15: bottomhp() ! 16: { bot2f=1; } ! 17: bottomspell() ! 18: { bot3f=1; } ! 19: bottomdo() ! 20: { ! 21: if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; } ! 22: if (bot2f) { bot2f=0; bot_hpx(); } ! 23: if (bot3f) { bot3f=0; bot_spellx(); } ! 24: } ! 25: ! 26: bot_linex() ! 27: { ! 28: register int i; ! 29: if (cbak[SPELLS] <= -50 || (always)) ! 30: { ! 31: cursor( 1,18); ! 32: if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]); ! 33: else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]); ! 34: lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]); ! 35: if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]); ! 36: else lprintf(" %-2d",(long)c[LEVEL]); ! 37: lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]); ! 38: lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ", ! 39: (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]); ! 40: lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:", ! 41: (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]); ! 42: ! 43: if ((level==0) || (wizard)) c[TELEFLAG]=0; ! 44: if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]); ! 45: lprintf(" Gold: %-6d",(long)c[GOLD]); ! 46: always=1; botside(); ! 47: c[TMP] = c[STRENGTH]+c[STREXTRA]; ! 48: for (i=0; i<100; i++) cbak[i]=c[i]; ! 49: return; ! 50: } ! 51: ! 52: botsub(makecode(SPELLS,8,18),"%3d"); ! 53: if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)"); ! 54: else botsub(makecode(SPELLMAX,12,18),"%2d) "); ! 55: botsub(makecode(HP,5,19),"%3d"); ! 56: botsub(makecode(HPMAX,9,19),"%3d"); ! 57: botsub(makecode(AC,21,18),"%-3d"); ! 58: botsub(makecode(WCLASS,30,18),"%-3d"); ! 59: botsub(makecode(EXPERIENCE,49,18),"%-9d"); ! 60: if (c[LEVEL] != cbak[LEVEL]) ! 61: { cursor(59,18); lprcat(class[c[LEVEL]-1]); } ! 62: if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d"); ! 63: else botsub(makecode(LEVEL,40,18)," %-2d"); ! 64: c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d"); ! 65: botsub(makecode(INTELLIGENCE,25,19),"%-2d"); ! 66: botsub(makecode(WISDOM,32,19),"%-2d"); ! 67: botsub(makecode(CONSTITUTION,39,19),"%-2d"); ! 68: botsub(makecode(DEXTERITY,46,19),"%-2d"); ! 69: botsub(makecode(CHARISMA,53,19),"%-2d"); ! 70: if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG])) ! 71: { ! 72: if ((level==0) || (wizard)) c[TELEFLAG]=0; ! 73: cbak[TELEFLAG] = c[TELEFLAG]; ! 74: cbak[CAVELEVEL] = level; cursor(59,19); ! 75: if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]); ! 76: } ! 77: botsub(makecode(GOLD,69,19),"%-6d"); ! 78: botside(); ! 79: } ! 80: ! 81: /* ! 82: special subroutine to update only the gold number on the bottomlines ! 83: called from ogold() ! 84: */ ! 85: bottomgold() ! 86: { ! 87: botsub(makecode(GOLD,69,19),"%-6d"); ! 88: /* botsub(GOLD,"%-6d",69,19); */ ! 89: } ! 90: ! 91: /* ! 92: special routine to update hp and level fields on bottom lines ! 93: called in monster.c hitplayer() and spattack() ! 94: */ ! 95: bot_hpx() ! 96: { ! 97: if (c[EXPERIENCE] != cbak[EXPERIENCE]) ! 98: { ! 99: recalc(); bot_linex(); ! 100: } ! 101: else botsub(makecode(HP,5,19),"%3d"); ! 102: } ! 103: ! 104: /* ! 105: special routine to update number of spells called from regen() ! 106: */ ! 107: bot_spellx() ! 108: { ! 109: botsub(makecode(SPELLS,9,18),"%2d"); ! 110: } ! 111: ! 112: /* ! 113: common subroutine for a more economical bottomline() ! 114: */ ! 115: static struct bot_side_def ! 116: { ! 117: int typ; ! 118: char *string; ! 119: } ! 120: bot_data[] = ! 121: { ! 122: STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro", ! 123: CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst", ! 124: GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity", ! 125: STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self", ! 126: CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3", ! 127: PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk" ! 128: }; ! 129: ! 130: botside() ! 131: { ! 132: register int i,idx; ! 133: for (i=0; i<17; i++) ! 134: { ! 135: idx = bot_data[i].typ; ! 136: if ((always) || (c[idx] != cbak[idx])) ! 137: { ! 138: if ((always) || (cbak[idx] == 0)) ! 139: { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else ! 140: if (c[idx]==0) { cursor(70,i+1); lprcat(" "); } ! 141: cbak[idx]=c[idx]; ! 142: } ! 143: } ! 144: always=0; ! 145: } ! 146: ! 147: static botsub(idx,str) ! 148: register int idx; ! 149: char *str; ! 150: { ! 151: register int x,y; ! 152: y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16; ! 153: if (c[idx] != cbak[idx]) ! 154: { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); } ! 155: } ! 156: ! 157: /* ! 158: * subroutine to draw only a section of the screen ! 159: * only the top section of the screen is updated. If entire lines are being ! 160: * drawn, then they will be cleared first. ! 161: */ ! 162: int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */ ! 163: draws(xmin,xmax,ymin,ymax) ! 164: int xmin,xmax,ymin,ymax; ! 165: { ! 166: register int i,idx; ! 167: if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */ ! 168: { ! 169: if (ymin==0) cl_up(79,ymax); ! 170: else for (i=ymin; i<ymin; i++) cl_line(1,i+1); ! 171: xmin = -1; ! 172: } ! 173: d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */ ! 174: drawscreen(); ! 175: if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/ ! 176: { ! 177: for (i=ymin; i<ymax; i++) ! 178: { ! 179: idx = bot_data[i].typ; ! 180: if (c[idx]) ! 181: { ! 182: cursor(70,i+1); lprcat(bot_data[i].string); ! 183: } ! 184: cbak[idx]=c[idx]; ! 185: } ! 186: } ! 187: } ! 188: ! 189: /* ! 190: drawscreen() ! 191: ! 192: subroutine to redraw the whole screen as the player knows it ! 193: */ ! 194: char screen[MAXX][MAXY],d_flag; /* template for the screen */ ! 195: drawscreen() ! 196: { ! 197: register int i,j,k; ! 198: int lastx,lasty; /* variables used to optimize the object printing */ ! 199: if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY) ! 200: { ! 201: d_flag=1; clear(); /* clear the screen */ ! 202: } ! 203: else ! 204: { ! 205: d_flag=0; cursor(1,1); ! 206: } ! 207: if (d_xmin<0) ! 208: d_xmin=0; /* d_xmin=-1 means display all without bottomline */ ! 209: ! 210: for (i=d_ymin; i<d_ymax; i++) ! 211: for (j=d_xmin; j<d_xmax; j++) ! 212: if (know[j][i]==0) screen[j][i] = ' '; else ! 213: if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else ! 214: if ((k=item[j][i])==OWALL) screen[j][i] = '#'; ! 215: else screen[j][i] = ' '; ! 216: ! 217: for (i=d_ymin; i<d_ymax; i++) ! 218: { ! 219: j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++; ! 220: /* was m=0 */ ! 221: if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */ ! 222: else ! 223: { /* search backwards for end of line */ ! 224: m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m; ! 225: if (j<=m) cursor(j+1,i+1); else continue; ! 226: } ! 227: while (j <= m) ! 228: { ! 229: if (j <= m-3) ! 230: { ! 231: for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000; ! 232: if (k < 1000) ! 233: { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); } ! 234: } ! 235: lprc(screen[j++][i]); ! 236: } ! 237: } ! 238: setbold(); /* print out only bold objects now */ ! 239: ! 240: for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++) ! 241: for (j=d_xmin; j<d_xmax; j++) ! 242: { ! 243: if (k=item[j][i]) ! 244: if (k != OWALL) ! 245: if ((know[j][i]) && (mitem[j][i]==0)) ! 246: if (objnamelist[k]!=' ') ! 247: { ! 248: if (lasty!=i+1 || lastx!=j) ! 249: cursor(lastx=j+1,lasty=i+1); else lastx++; ! 250: lprc(objnamelist[k]); ! 251: } ! 252: } ! 253: ! 254: resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); } ! 255: oldx=99; ! 256: d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */ ! 257: } ! 258: ! 259: /* ! 260: showcell(x,y) ! 261: ! 262: subroutine to display a cell location on the screen ! 263: */ ! 264: showcell(x,y) ! 265: int x,y; ! 266: { ! 267: register int i,j,k,m; ! 268: if (c[BLINDCOUNT]) return; /* see nothing if blind */ ! 269: if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; } ! 270: else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; } ! 271: ! 272: if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1; ! 273: if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1; ! 274: ! 275: for (j=miny; j<=maxy; j++) ! 276: for (m=minx; m<=maxx; m++) ! 277: if (know[m][j]==0) ! 278: { ! 279: cursor(m+1,j+1); ! 280: x=maxx; while (know[x][j]) --x; ! 281: for (i=m; i<=x; i++) ! 282: { ! 283: if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]); ! 284: else switch(k=item[i][j]) ! 285: { ! 286: case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: ! 287: case OIVDARTRAP: case OIVTRAPDOOR: ! 288: lprc(objnamelist[k]); break; ! 289: ! 290: default: setbold(); lprc(objnamelist[k]); resetbold(); ! 291: }; ! 292: know[i][j]=1; ! 293: } ! 294: m = maxx; ! 295: } ! 296: } ! 297: ! 298: /* ! 299: this routine shows only the spot that is given it. the spaces around ! 300: these coordinated are not shown ! 301: used in godirect() in monster.c for missile weapons display ! 302: */ ! 303: show1cell(x,y) ! 304: int x,y; ! 305: { ! 306: if (c[BLINDCOUNT]) return; /* see nothing if blind */ ! 307: cursor(x+1,y+1); ! 308: if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]); ! 309: else switch(k=item[x][y]) ! 310: { ! 311: case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: ! 312: case OIVDARTRAP: case OIVTRAPDOOR: ! 313: lprc(objnamelist[k]); break; ! 314: ! 315: default: setbold(); lprc(objnamelist[k]); resetbold(); ! 316: }; ! 317: know[x][y]|=1; /* we end up knowing about it */ ! 318: } ! 319: ! 320: /* ! 321: showplayer() ! 322: ! 323: subroutine to show where the player is on the screen ! 324: cursor values start from 1 up ! 325: */ ! 326: showplayer() ! 327: { ! 328: cursor(playerx+1,playery+1); ! 329: oldx=playerx; oldy=playery; ! 330: } ! 331: ! 332: /* ! 333: moveplayer(dir) ! 334: ! 335: subroutine to move the player from one room to another ! 336: returns 0 if can't move in that direction or hit a monster or on an object ! 337: else returns 1 ! 338: nomove is set to 1 to stop the next move (inadvertent monsters hitting ! 339: players when walking into walls) if player walks off screen or into wall ! 340: */ ! 341: short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 }; ! 342: short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 }; ! 343: moveplayer(dir) ! 344: int dir; /* from = present room # direction = [1-north] ! 345: [2-east] [3-south] [4-west] [5-northeast] ! 346: [6-northwest] [7-southeast] [8-southwest] ! 347: if direction=0, don't move--just show where he is */ ! 348: { ! 349: register int k,m,i,j; ! 350: if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/ ! 351: k = playerx + diroffx[dir]; m = playery + diroffy[dir]; ! 352: if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); } ! 353: i = item[k][m]; j = mitem[k][m]; ! 354: if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */ ! 355: if (k==33 && m==MAXY-1 && level==1) ! 356: { ! 357: newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++) ! 358: if (item[k][m]==OENTRANCE) ! 359: { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); } ! 360: } ! 361: if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/ ! 362: lastpx = playerx; lastpy = playery; ! 363: playerx = k; playery = m; ! 364: if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1); ! 365: } ! 366: ! 367: /* ! 368: * function to show what magic items have been discovered thus far ! 369: * enter with -1 for just spells, anything else will give scrolls & potions ! 370: */ ! 371: static int lincount,count; ! 372: seemagic(arg) ! 373: int arg; ! 374: { ! 375: register int i,number; ! 376: count = lincount = 0; nosignal=1; ! 377: ! 378: if (arg== -1) /* if display spells while casting one */ ! 379: { ! 380: for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++; ! 381: number = (number+2)/3 + 4; /* # lines needed to display */ ! 382: cl_up(79,number); cursor(1,1); ! 383: } ! 384: else ! 385: { ! 386: resetscroll(); clear(); ! 387: } ! 388: ! 389: lprcat("The magic spells you have discovered thus far:\n\n"); ! 390: for (i=0; i<SPNUM; i++) ! 391: if (spelknow[i]) ! 392: { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); } ! 393: ! 394: if (arg== -1) ! 395: { ! 396: seepage(); more(); nosignal=0; ! 397: draws(0,MAXX,0,number); return; ! 398: } ! 399: ! 400: lincount += 3; if (count!=0) { count=2; seepage(); } ! 401: ! 402: lprcat("\nThe magic scrolls you have found to date are:\n\n"); ! 403: count=0; ! 404: for (i=0; i<MAXSCROLL; i++) ! 405: if (scrollname[i][0]) ! 406: if (scrollname[i][1]!=' ') ! 407: { lprintf("%-26s",&scrollname[i][1]); seepage(); } ! 408: ! 409: lincount += 3; if (count!=0) { count=2; seepage(); } ! 410: ! 411: lprcat("\nThe magic potions you have found to date are:\n\n"); ! 412: count=0; ! 413: for (i=0; i<MAXPOTION; i++) ! 414: if (potionname[i][0]) ! 415: if (potionname[i][1]!=' ') ! 416: { lprintf("%-26s",&potionname[i][1]); seepage(); } ! 417: ! 418: if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen(); ! 419: } ! 420: ! 421: /* ! 422: * subroutine to paginate the seemagic function ! 423: */ ! 424: seepage() ! 425: { ! 426: if (++count==3) ! 427: { ! 428: lincount++; count=0; lprc('\n'); ! 429: if (lincount>17) { lincount=0; more(); clear(); } ! 430: } ! 431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.