|
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 g
Length: 19070 (0x4a7e) Types: TextFile Names: »game.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Xwanderer/game.c.orig«
#include "wand_head.h" #define viable(x,y) ((screen[y][x] == ' ') || (screen[y][x] == ':') ||\ (screen[y][x] == '@') || (screen[y][x] == '+')) && (y >= 0) &&\ (x >= 0) && (y < NOOFROWS) && (x < ROWLEN) typedef struct mon_rec { int x,y,mx,my; char under; struct mon_rec *next; }; typedef struct { int d[2] } direction; #ifdef XWANDER int playerfacing = 0; int tinymode = 0; extern int do_repaint; #endif #ifndef GAMEDEV extern int jumpscreen(); extern void showpass(); #endif extern void draw_symbol(); extern void display(); extern int fall(); extern void map(); /* Add a spirit to the chain */ struct mon_rec *make_monster(x,y) int x,y; { struct mon_rec *malloc(), *monster; if((monster = malloc(sizeof(struct mon_rec))) == NULL) return NULL; monster->x = x; monster->y = y; monster->mx = 1; /* always start moving RIGHT. (fix later) */ monster->my = 0; monster->under = ' '; monster->next = NULL; return monster; } /* 'follow lefthand wall' algorithm for sprites */ direction new_direction(screen,x,y,bx,by) int x,y,bx,by; char screen[NOOFROWS][ROWLEN+1]; { direction out; if(viable((x+by),(y-bx))) { out.d[0] = by; out.d[1] = -bx; return out; } if(viable((x+bx),(y+by))) { out.d[0] = bx; out.d[1] = by; return out; } if(viable((x-by),(y+bx))) { out.d[0] = -by; out.d[1] = bx; return out; } if(viable((x-bx),(y-by))) { out.d[0] = -bx; out.d[1] = -by; return out; } out.d[0] = -bx; out.d[1] = -by; return out; } /* Actual game function - Calls fall() to move boulders and arrows recursively */ #ifndef GAMEDEV char *playscreen(num,screen,score,bell,maxmoves,keys) int num; #else char *playscreen(num,screen,score,bell,maxmoves,keys) #endif int maxmoves, *bell, *score; char screen[NOOFROWS][ROWLEN+1], keys[10]; { int x,y,nx,ny,deadyet =0, sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1, bx, by, nbx, nby, newnum, diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection; char (*frow)[ROWLEN+1] = screen, ch, buffer[25], howdead[25]; direction new_disp; struct mon_rec *monster,*mon_ptr, *current; mon_ptr = NULL; for(x=0;x<=ROWLEN;x++) for(y=0;y<NOOFROWS;y++) { if((screen[y][x] == '*')||(screen[y][x] == '+')) diamonds++; if(screen[y][x] == 'A') /* note teleport arrival point & */ { /* replace with space */ tx = x; ty = y; screen[y][x] = ' '; } if(screen[y][x] == '@') { sx = x; sy = y; } if(screen[y][x] == 'M') /* Put megamonster in */ { mx = x; my = y; } if(screen[y][x] == 'S') /* link small monster to pointer chain */ { if((monster = make_monster(x,y)) == NULL) { strcpy(howdead,"running out of memory"); return howdead; } if(mon_ptr == NULL) current = mon_ptr = monster; else current = current->next = monster; } if(screen[y][x] == '-') screen[y][x] = ' '; }; x=sx; y=sy; if((x == -1)&&(y == -1)) /* no start position in file ? */ { #ifdef GAMEDEV strcpy(howdead,"no start position!"); #else strcpy(howdead,"a screen design error"); #endif return(howdead); } #ifndef XWANDER move(0,48); (void) addstr("Score\t Diamonds"); move(1,48); (void) addstr("\tFound\tTotal"); move(3,48); (void) sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); move(6,48); (void) sprintf(buffer,"Current screen %d",num); (void) addstr(buffer); if(maxmoves != 0) (void) sprintf(buffer,"Moves remaining = %d ",maxmoves); else { (void) strcpy(buffer," Unlimited moves "); maxmoves = -1; }; move(15,48); (void) addstr(buffer); if(mx != -1) /* tell player if monster exists */ draw_symbol(48,10,'M'); else draw_symbol(48,10,' '); #else repaint_score(*score, nf, diamonds, num, maxmoves, mx); #endif display(sx,sy,frow,*score); /* ACTUAL GAME FUNCTION - Returns method of death in string */ while(deadyet == 0) { #ifndef XWANDER ch = getchar(); #else ch = getchar(sx, sy, frow, score, nf, diamonds, num, maxmoves, mx); #endif nx=x; ny=y; #ifdef XWANDER if(ch == keys[3]) { playerfacing = 0; nx++; } if(ch == keys[2]) { playerfacing = 1; nx--; } #else if(ch == keys[3]) nx++; if(ch == keys[2]) nx--; #endif if((ch == keys[1]) && (y<(NOOFROWS-1))) ny++; if(ch == keys[0]) ny--; if(ch == '1') { #ifndef XWANDER move(10,45); *bell = 1; (void) addstr("Bell ON "); dobeep(); move(16,0); refresh(); #else *bell = 1; score_message(12,"Bell ON "); #endif } if(ch == '0') { #ifndef XWANDER *bell = 0; move(10,45); (void) addstr("Bell OFF"); move(16,0); refresh(); #else *bell = 1; score_message(12,"Bell OFF"); #endif } if(ch == '~') /* level jump */ #ifdef GAMEDEV { strcpy(howdead,"~~"); return(howdead); } #else { if((newnum = jumpscreen(num)) == 0) { strcpy(howdead,"a jump error."); return howdead; } if(newnum > num) { sprintf(howdead,"~%c",newnum); return howdead; } dobeep(); } #endif if(ch == '!') { #ifdef XWANDER if (tinymode) dobeep(); else { #endif map(frow); display(sx,sy,frow,*score); #ifdef XWANDER } #endif } #ifdef XWANDER if (ch == 't') { if (tinymode) { tinymode = 0; sx = x - 5; if (sx < 0) sx = 0; sy = y - 3; if (sy < 0) sy = 0; XClearArea(dpy, win, 5,5,ICON_WIDE*11, ICON_HIGH*7,0); display(sx,sy,frow,*score); } else { sx = 5; sy = 3; tinymode = 1; drawmap(frow,1); } } #endif if (ch == '?') { do_help(keys); #ifdef XWANDER do_repaint = 1; if (tinymode) drawmap(frow,1); else #endif display(sx,sy,frow,*score); } if(ch == 'q') { strcpy(howdead,"quitting the game"); return howdead; } if(screen[ny][nx] == 'C') { screen[ny][nx] = ':'; *score+=4; if (*bell) dobeep(); if(maxmoves != -1) maxmoves+=250; } switch(screen[ny][nx]) { case '@': break; case '*': *score+=9; if (*bell) dobeep(); nf++; case ':': *score+=1; #ifndef XWANDER move(3,48); sprintf(buffer,"%d\t %d",*score,nf); (void) addstr(buffer); #else score_message(2,"%7d %3d %3d", *score, nf, diamonds); #endif case ' ': screen[y][x] = ' '; screen[ny][nx] = '@'; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); #else draw_symbol((x-sx+5),(y-sy+3),' '); draw_symbol((nx-sx+5),(ny-sy+3),'@'); #endif if(deadyet ==0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if((deadyet ==0) && (nx != (x+1))) deadyet = fall(&mx,&my,x+1,y,sx,sy,screen,howdead); if((deadyet ==0) && (nx != (x-1))) deadyet = fall(&mx,&my,x-1,y,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x+1,y+1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x-1,y+1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x-1,y-1,sx,sy,screen,howdead); if((deadyet ==0) && (ny != (y+1))) deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead); if((deadyet ==0) && (ny != (y-1))) deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x+1,y-1,sx,sy,screen,howdead); #ifndef XWANDER move(16,0); refresh(); #endif y = ny; x = nx; break; case 'O': if(screen[y][nx*2-x] == 'M') { screen[y][nx*2-x] = ' '; mx = my = -1; if(*bell) dobeep(); *score+=100; #ifndef XWANDER move(3,48); sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); #else score_message(2,"%7d %3d %3d", *score, nf, diamonds); display_monster(mx); #endif } if(screen[y][nx*2-x] == ' ') { screen[y][nx*2-x] = 'O'; screen[y][x] = ' '; screen[ny][nx] = '@'; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O'); #else draw_symbol((x-sx+5),(y-sy+3),' '); draw_symbol((nx-sx+5),(ny-sy+3),'@'); draw_symbol((nx*2-x-sx+5),(y-sy+3),'O'); #endif if(deadyet==0) deadyet = fall(&mx,&my,nx*2-x,y+1,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x*2-nx,y,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead); #ifndef XWANDER move(16,0); refresh(); #endif y = ny; x = nx; } break; case '<': case '>': if(screen[ny*2-y][x] == 'M') { screen[ny*2-y][x] = ' '; mx = my = -1; if(*bell) dobeep(); *score+=100; #ifndef XWANDER move(3,48); sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); #else score_message(2,"%7d %3d %3d", *score, nf, diamonds); display_monster(mx); #endif } if(screen[ny*2-y][x] == ' ') { screen[ny*2-y][x] = screen[ny][nx]; screen[y][x] = ' '; screen[ny][nx] = '@'; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]); #else draw_symbol((x-sx+5),(y-sy+3),' '); draw_symbol((nx-sx+5),(ny-sy+3),'@'); draw_symbol((x-sx+5),(ny*2-y-sy+3),screen[ny*2-y][x]); #endif if(deadyet == 0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x-1,ny*2-y,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x+1,ny*2-y,sx,sy,screen,howdead); #ifndef XWANDER move(16,0); refresh(); #endif y = ny; x = nx; } break; case '!': strcpy(howdead,"an exploding landmine"); deadyet = 1; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); move(16,0); refresh(); #else draw_symbol((x-sx+5),(y-sy+3),' '); draw_symbol((nx-sx+5),(ny-sy+3),'@'); #endif break; case 'X': if(nf == diamonds) { *score+=250; if(*bell) dobeep(); #ifndef GAMEDEV showpass(num); return NULL; #else strcpy(howdead,"finishing the screen."); return howdead; #endif } break; case 'T': if(tx > -1) { screen[ny][nx] = ' '; screen[y][x] = ' '; #ifdef XWANDER if (tinymode) { draw_symbol(nx,ny,' '); draw_symbol(x,y,' '); draw_symbol(tx,ty,'@'); } #endif lx = x; ly = y; y = ty; x = tx; screen[y][x] = '@'; #ifdef XWANDER if (!tinymode) { #endif sx = x; sy = y; *score += 20; #ifdef XWANDER } #endif #ifndef XWANDER display(sx,sy,frow,*score); #else if (!tinymode) display(sx,sy,frow,*score); #endif deadyet = fall(&mx,&my,nx,ny,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx,ly,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,screen,howdead); #ifndef XWANDER move(16,0); refresh(); #endif } else { screen[ny][nx] = ' '; #ifndef XWANDER printf("Teleport out of order"); #else erase_message(0); message(0,"Teleport out of order"); if (*bell) dobeep(); #endif } break; case 'M': strcpy(howdead,"a hungry monster"); deadyet = 1; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); move(16,0); refresh(); #else draw_symbol((x-sx+5),(y-sy+3),' '); #endif break; case 'S': strcpy(howdead,"walking into a monster"); deadyet = 1; #ifndef XWANDER draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); move(16,0); refresh(); #else draw_symbol((x-sx+5),(y-sy+3),' '); #endif break; default: break; } if((y == ny) && (x == nx) && (maxmoves>0)) { #ifndef XWANDER (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves); move(15,48); (void) addstr(buffer); #else score_message(15,"Moves Remaining = %d ", --maxmoves); #endif } if(maxmoves == 0) { #ifdef GAMEDEV #ifdef XWANDER message(0,"You ran out of time!"); dobeep(); #else addstr("You ran out of time! \007\007"); refresh(); #endif #else strcpy(howdead,"running out of time"); return(howdead); #endif } #ifdef XWANDER if (!tinymode) { #endif if ((x<(sx-3))&& (deadyet ==0)) /* screen scrolling if necessary */ { sx-=6; if(sx < 4) sx = 4; display(sx,sy,frow,*score); } if ((y<(sy-2))&& (deadyet == 0)) { sy-=5; if(sy < 2) sy = 2; display(sx,sy,frow,*score); } if ((x>(sx+3)) && (deadyet == 0)) { sx+=6; if(sx>(ROWLEN -5)) sx = ROWLEN -5; display(sx,sy,frow,*score); } if ((y>(sy+2))&& (deadyet ==0)) { sy+=5; if(sy > (NOOFROWS-3)) sy = NOOFROWS -3; display(sx,sy,frow,*score); } #ifdef XWANDER } #endif /* MONSTER SECTION - Put all these in a separate function later */ if(mx == -2) /* has the monster been killed ? */ { *score+=100; mx = my = -1; #ifndef XWANDER move(3,48); sprintf(buffer,"%d\t %d\t",*score,nf); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); #else score_message(2,"%7d %3d %3d", *score, nf, diamonds); display_monster(mx); #endif } if(mx != -1) /* no? then move that monster ! */ { screen[my][mx] = ' '; if(mx>x) xdirection = -1; else xdirection = 1; #ifndef XWANDER if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6))) draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' '); #else if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)) || tinymode) draw_symbol((mx-sx+5),(my-sy+3),' '); #endif if((hd = (mx-x))<0) hd = -hd; if((vd = (my-y))<0) vd = -vd; if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))) mx+=xdirection; else { if(my>y) ydirection = -1; else ydirection = 1; if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@')) my+=ydirection; else if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')) mx+=xdirection; } #ifndef XWANDER if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6))) draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M'); #else if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)) || tinymode) draw_symbol((mx-sx+5),(my-sy+3),'M'); #endif if(screen[my][mx] == '@') /* ha! gottim! */ { strcpy(howdead,"a hungry monster"); #ifndef XWANDER move(16,0); refresh(); #endif return(howdead); } screen[my][mx] = 'M'; #ifndef XWANDER move(16,0); refresh(); #endif } current = monster = mon_ptr; while((monster != NULL)&&(!deadyet))/* deal with those little monsters */ { new_disp = new_direction(screen, monster->x, monster->y, monster->mx, monster->my ); screen[monster->y][monster->x] = monster->under; #ifndef XWANDER if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under); #else if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)) || tinymode) draw_symbol((monster->x-sx+5),(monster->y-sy+3),monster->under); #endif if(monster->under == ' ') deadyet = deadyet | fall(&mx,&my,monster->x,monster->y,sx,sy,screen,howdead); monster->mx = new_disp.d[0]; monster->my = new_disp.d[1]; monster->x += monster->mx; monster->y += monster->my; monster->under = screen[monster->y][monster->x]; screen[monster->y][monster->x] = 'S'; /* move into new space */ #ifndef XWANDER if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S'); #else if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)) || tinymode) draw_symbol((monster->x-sx+5),(monster->y-sy+3),'S'); #endif if(monster->under == '@') /* monster hit you? */ { strcpy(howdead,"the little monsters"); #ifndef XWANDER move(16,0); refresh(); #endif return(howdead); } if(monster->under == '+') /* monster hit cage? */ { *score +=20; if(*bell) dobeep(); if(monster == mon_ptr) /* remove from chain */ mon_ptr = mon_ptr->next; else current->next = monster-> next; screen[monster->y][monster->x] = '*'; #ifndef XWANDER if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*'); #else if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)) || tinymode) draw_symbol((monster->x-sx+5),(monster->y-sy+3),'*'); #endif } if(monster->under == 'S') monster->under = ' '; if(monster != mon_ptr) current = current->next; monster = monster->next; #ifdef GAMEDEV if(deadyet != 0) { #ifndef XWANDER move(16,0); addstr("You are dead, killed by "); addstr(howdead); addstr("\nPress any key to come back to life."); refresh(); ch = getchar(); move(16,0); addstr(" \n"); addstr(" "); move(16,0); refresh(); deadyet = 0; #else erase_message(0); erase_message(1); message(0,"You are dead. killed by %s.",howdead); message(1,"Press any key to come back to life."); (void)getchar(-1); erase_message(0); erase_message(1); deadyet = 0; #endif } #endif #ifndef XWANDER move(16,0); refresh(); #endif } } return(howdead); }