|
|
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: 14429 (0x385d)
Types: TextFile
Names: »gamedev.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Xwanderer/gamedev.c«
#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;
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 */
char *playscreen(screen,score,bell,maxmoves,keys)
int maxmoves,
*bell,
*score;
char screen[NOOFROWS][ROWLEN+1],
keys[6];
{
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, num = 1,
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 ? */
{
strcpy(howdead,"no start position!");
return(howdead);
}
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,' ');
display(sx,sy,frow,*score);
/* ACTUAL GAME FUNCTION - Returns method of death in string */
while(deadyet == 0)
{
ch = getchar();
nx=x;
ny=y;
if(ch == keys[3])
nx++;
if(ch == keys[2])
nx--;
if((ch == keys[1]) && (y<(NOOFROWS-1)))
ny++;
if(ch == keys[0])
ny--;
if(ch == '1')
{
move(10,45);
*bell = 1;
(void) addstr("Bell ON ");
printf("\007");
move(16,0);
refresh();
}
if(ch == '0')
{
*bell = 0;
move(10,45);
(void) addstr("Bell OFF");
move(16,0);
refresh();
}
if(ch == '~') /* level jump */
{
strcpy(howdead,"~~");
return howdead;
}
if(ch == '!')
{
map(frow);
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)
printf("\007");
if(maxmoves != -1)
maxmoves+=250;
}
switch(screen[ny][nx])
{
case '@': break;
case '*': *score+=9;
if (*bell)
printf("\007");
nf++;
case ':': *score+=1;
move(3,48);
sprintf(buffer,"%d\t %d",*score,nf);
(void) addstr(buffer);
case ' ':
screen[y][x] = ' ';
screen[ny][nx] = '@';
draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
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);
move(16,0);
refresh();
y = ny;
x = nx;
break;
case 'O':
if(screen[y][nx*2-x] == 'M')
{
screen[y][nx*2-x] = ' ';
mx = my = -1;
if(*bell)
printf("\007");
*score+=100;
move(3,48);
sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
(void) addstr(buffer);
draw_symbol(48,10,' ');
move(16,0);
refresh();
}
if(screen[y][nx*2-x] == ' ')
{
screen[y][nx*2-x] = 'O';
screen[y][x] = ' ';
screen[ny][nx] = '@';
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');
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);
move(16,0);
refresh();
y = ny;
x = nx;
}
break;
case '<':
case '>':
if(screen[ny*2-y][x] == 'M')
{
screen[ny*2-y][x] = ' ';
mx = my = -1;
if(*bell)
printf("\007");
*score+=100;
move(3,48);
sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
(void) addstr(buffer);
draw_symbol(48,10,' ');
move(16,0);
refresh();
}
if(screen[ny*2-y][x] == ' ')
{
screen[ny*2-y][x] = screen[ny][nx];
screen[y][x] = ' ';
screen[ny][nx] = '@';
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]);
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);
move(16,0);
refresh();
y = ny;
x = nx;
}
break;
case '!':
strcpy(howdead,"an exploding landmine");
deadyet = 1;
draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
move(16,0);
refresh();
break;
case 'X':
if(nf == diamonds)
{
*score+=250;
if(*bell)
printf("\007");
strcpy(howdead,"finishing the screen.");
return howdead;
}
break;
case 'T':
if(tx > -1)
{
screen[ny][nx] = ' ';
screen[y][x] = ' ';
lx = x;
ly = y;
y = ty;
x = tx;
screen[y][x] = '@';
sx = x;
sy = y;
*score += 20;
display(sx,sy,frow,*score);
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);
move(16,0);
refresh();
}
else
{
screen[ny][nx] = ' ';
printf("Teleport out of order");
}
break;
case 'M':
strcpy(howdead,"a hungry monster");
deadyet = 1;
draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
move(16,0);
refresh();
break;
case 'S':
strcpy(howdead,"walking into a monster");
deadyet = 1;
draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
move(16,0);
refresh();
break;
default:
break;
}
if((y == ny) && (x == nx) && (maxmoves>0))
{
(void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
move(15,48);
(void) addstr(buffer);
}
if(maxmoves == 0)
{
addstr("You ran out of time! \007\007");
refresh();
}
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);
}
/* MONSTER SECTION - Put all these in a separate function later */
if(mx == -2) /* has the monster been killed ? */
{
*score+=100;
mx = my = -1;
move(3,48);
sprintf(buffer,"%d\t %d\t",*score,nf);
(void) addstr(buffer);
draw_symbol(48,10,' ');
move(16,0);
refresh();
}
if(mx != -1) /* no? then move that monster ! */
{
screen[my][mx] = ' ';
if(mx>x)
xdirection = -1;
else
xdirection = 1;
if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
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;
}
if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
if(screen[my][mx] == '@') /* ha! gottim! */
{
strcpy(howdead,"a hungry monster");
move(16,0);
refresh();
deadyet = 1;
screen[my][mx] = 'M';
}
screen[my][mx] = 'M';
move(16,0);
refresh();
}
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;
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);
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 */
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');
if(monster->under == '@') /* monster hit you? */
{
strcpy(howdead,"the little monsters");
move(16,0);
refresh();
deadyet = 1;
monster->under = ' ';
}
if(monster->under == '+') /* monster hit cage? */
{
*score +=20;
if(*bell)
printf("\007");
if(monster == mon_ptr) /* remove from chain */
mon_ptr = mon_ptr->next;
else current->next = monster-> next;
screen[monster->y][monster->x] = '*';
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,'*');
}
if(monster->under == 'S')
monster->under = ' ';
if(monster != mon_ptr)
current = current->next;
monster = monster->next;
move(16,0);
refresh();
}
if(deadyet != 0)
{
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;
}
}
return(howdead);
}