/* display.c Larn is copyrighted 1986 by Noah Morgan. */ /* $FreeBSD: src/games/larn/display.c,v 1.4 1999/11/16 02:57:21 billf Exp $ */ /* $DragonFly: src/games/larn/display.c,v 1.3 2006/08/26 17:05:05 pavalos Exp $ */ #include "header.h" #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c)) static int minx,maxx,miny,maxy,k,m; static char bot1f=0,bot2f=0,bot3f=0; char always=0; static void bot_hpx(void); static void bot_spellx(void); static void botside(void); static void botsub(int, const char *); static void seepage(void); /* bottomline() now for the bottom line of the display */ void bottomline(void) { recalc(); bot1f=1; } void bottomhp(void) { bot2f=1; } void bottomspell(void) { bot3f=1; } void bottomdo(void) { if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; } if (bot2f) { bot2f=0; bot_hpx(); } if (bot3f) { bot3f=0; bot_spellx(); } } void bot_linex(void) { int i; if (cbak[SPELLS] <= -50 || (always)) { cursor( 1,18); if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]); else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]); lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]); if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]); else lprintf(" %-2d",(long)c[LEVEL]); lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]); lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ", (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]); lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:", (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]); if ((level==0) || (wizard)) c[TELEFLAG]=0; if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[(int)level]); lprintf(" Gold: %-6d",(long)c[GOLD]); always=1; botside(); c[TMP] = c[STRENGTH]+c[STREXTRA]; for (i=0; i<100; i++) cbak[i]=c[i]; return; } botsub(makecode(SPELLS,8,18),"%3d"); if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)"); else botsub(makecode(SPELLMAX,12,18),"%2d) "); botsub(makecode(HP,5,19),"%3d"); botsub(makecode(HPMAX,9,19),"%3d"); botsub(makecode(AC,21,18),"%-3d"); botsub(makecode(WCLASS,30,18),"%-3d"); botsub(makecode(EXPERIENCE,49,18),"%-9d"); if (c[LEVEL] != cbak[LEVEL]) { cursor(59,18); lprcat(class[c[LEVEL]-1]); } if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d"); else botsub(makecode(LEVEL,40,18)," %-2d"); c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d"); botsub(makecode(INTELLIGENCE,25,19),"%-2d"); botsub(makecode(WISDOM,32,19),"%-2d"); botsub(makecode(CONSTITUTION,39,19),"%-2d"); botsub(makecode(DEXTERITY,46,19),"%-2d"); botsub(makecode(CHARISMA,53,19),"%-2d"); if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG])) { if ((level==0) || (wizard)) c[TELEFLAG]=0; cbak[TELEFLAG] = c[TELEFLAG]; cbak[CAVELEVEL] = level; cursor(59,19); if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[(int)level]); } botsub(makecode(GOLD,69,19),"%-6d"); botside(); } /* special subroutine to update only the gold number on the bottomlines called from ogold() */ void bottomgold(void) { botsub(makecode(GOLD,69,19),"%-6d"); } /* special routine to update hp and level fields on bottom lines called in monster.c hitplayer() and spattack() */ static void bot_hpx(void) { if (c[EXPERIENCE] != cbak[EXPERIENCE]) { recalc(); bot_linex(); } else botsub(makecode(HP,5,19),"%3d"); } /* special routine to update number of spells called from regen() */ static void bot_spellx(void) { botsub(makecode(SPELLS,9,18),"%2d"); } /* common subroutine for a more economical bottomline() */ static struct bot_side_def { int typ; const char *string; } bot_data[] = { { STEALTH, "stealth" }, { UNDEADPRO, "undead pro" }, { SPIRITPRO, "spirit pro" }, { CHARMCOUNT, "Charm" }, { TIMESTOP, "Time Stop" }, { HOLDMONST, "Hold Monst" }, { GIANTSTR, "Giant Str" }, { FIRERESISTANCE, "Fire Resit" }, { DEXCOUNT, "Dexterity" }, { STRCOUNT, "Strength" }, { SCAREMONST, "Scare" }, { HASTESELF, "Haste Self" }, { CANCELLATION, "Cancel" }, { INVISIBILITY, "Invisible" }, { ALTPRO, "Protect 3" }, { PROTECTIONTIME, "Protect 2" }, { WTW, "Wall-Walk"} }; static void botside(void) { int i,idx; for (i=0; i<17; i++) { idx = bot_data[i].typ; if ((always) || (c[idx] != cbak[idx])) { if ((always) || (cbak[idx] == 0)) { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else if (c[idx]==0) { cursor(70,i+1); lprcat(" "); } cbak[idx]=c[idx]; } } always=0; } static void botsub(int idx, const char *str) { int x,y; y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16; if (c[idx] != cbak[idx]) { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); } } /* * subroutine to draw only a section of the screen * only the top section of the screen is updated. If entire lines are being * drawn, then they will be cleared first. */ int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */ void draws(int xmin, int xmax, int ymin, int ymax) { int i,idx; if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */ { if (ymin==0) cl_up(79,ymax); else for (i=ymin; i= d_xmax) m=d_xmin; /* don't search backwards if blank line */ else { /* search backwards for end of line */ m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m; if (j<=m) cursor(j+1,i+1); else continue; } while (j <= m) { if (j <= m-3) { for (l=j; l<=j+3; l++) if (screen[l][i] != ' ') l=1000; if (l < 1000) { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); } } lprc(screen[j++][i]); } } setbold(); /* print out only bold objects now */ for (lastx=lasty=127, i=d_ymin; i MAXX-1) maxx = MAXX-1; if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1; for (j=miny; j<=maxy; j++) for (n=minx; n<=maxx; n++) if (know[n][j]==0) { cursor(n+1,j+1); x=maxx; while (know[x][j]) --x; for (i=n; i<=x; i++) { if ((l=mitem[i][j]) != 0) lprc(monstnamelist[l]); else switch(l=item[i][j]) { case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: case OIVDARTRAP: case OIVTRAPDOOR: lprc(objnamelist[l]); break; default: setbold(); lprc(objnamelist[l]); resetbold(); }; know[i][j]=1; } n = maxx; } } /* this routine shows only the spot that is given it. the spaces around these coordinated are not shown used in godirect() in monster.c for missile weapons display */ void show1cell(int x, int y) { if (c[BLINDCOUNT]) return; /* see nothing if blind */ cursor(x+1,y+1); if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]); else switch(k=item[x][y]) { case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV: case OIVDARTRAP: case OIVTRAPDOOR: lprc(objnamelist[k]); break; default: setbold(); lprc(objnamelist[k]); resetbold(); }; know[x][y]|=1; /* we end up knowing about it */ } /* showplayer() subroutine to show where the player is on the screen cursor values start from 1 up */ void showplayer(void) { cursor(playerx+1,playery+1); oldx=playerx; oldy=playery; } /* moveplayer(dir) subroutine to move the player from one room to another returns 0 if can't move in that direction or hit a monster or on an object else returns 1 nomove is set to 1 to stop the next move (inadvertent monsters hitting players when walking into walls) if player walks off screen or into wall */ short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 }; short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 }; int moveplayer(int dir) /* from = present room # direction = [1-north] [2-east] [3-south] [4-west] [5-northeast] [6-northwest] [7-southeast] [8-southwest] if direction=0, don't move--just show where he is */ { int l,n,i,j; if (c[CONFUSE]) if (c[LEVEL]=MAXX || n<0 || n>=MAXY) { nomove=1; return(yrepcount = 0); } i = item[l][n]; j = mitem[l][n]; if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */ if (l==33 && n==MAXY-1 && level==1) { newcavelevel(0); for (l=0; l0) { hitmonster(l,n); return(yrepcount = 0); } /* hit a monster*/ lastpx = playerx; lastpy = playery; playerx = l; playery = n; if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1); } /* * function to show what magic items have been discovered thus far * enter with -1 for just spells, anything else will give scrolls & potions */ static int lincount,count; void seemagic(int arg) { int i,number = 0; count = lincount = 0; nosignal=1; if (arg== -1) /* if display spells while casting one */ { for (number=i=0; i17) { lincount=0; more(); clear(); } } }