1127 lines
90 KiB
HolyC
1127 lines
90 KiB
HolyC
RegSetDftEntry("TempleOS/TimeOut","I64 best_score=0;\n");
|
|
RegExeBranch("TempleOS/TimeOut");
|
|
|
|
#define MAP_HEIGHT 4096
|
|
#define BULLET_LEN 10
|
|
#define BULLET_SPEED 5
|
|
|
|
#define MAX_BULLETS 128
|
|
class Bullet
|
|
{
|
|
I64 x,y,dx,dy,dx2,dy2;
|
|
Bool dead,missile,pad[6];
|
|
} b[MAX_BULLETS];
|
|
I64 bullets_fired,missiles_fired;
|
|
|
|
I64 x,y,dx,dy,finish_line;
|
|
F64 é,t0,tf,snd_timeout;
|
|
|
|
#define PHASES_GROUPS 8
|
|
#define MAX_ENEMY (PHASES_GROUPS*64)
|
|
#define MAX_FRIENDLY (PHASES_GROUPS*16)
|
|
#define MAX_UNIT (MAX_FRIENDLY+MAX_ENEMY)
|
|
#define HACK_DIST 5
|
|
class Unit
|
|
{
|
|
I64 x,y,best_dd;
|
|
F64 é,phase,die_time,corpse_timeout;
|
|
Bool friendly,dead,tank,missile_strike,pad[4];
|
|
} u[MAX_UNIT];
|
|
|
|
I64 total_score,friendly_fire,enemy_by_friendly,friendly_left,enemy_left,
|
|
main_loop_pass;
|
|
Bool game_over;
|
|
$BG,14$
|
|
|
|
|
|
|
|
$SP,"<1>",BI=1$
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"<2>",BI=2$
|
|
|
|
|
|
$SP,"<3>",BI=3$
|
|
|
|
|
|
|
|
$SP,"<4>",BI=4$
|
|
|
|
|
|
|
|
$SP,"<5>",BI=5$
|
|
|
|
|
|
|
|
U8 *friendly_imgs[4]={$IB,"<4>",BI=4$,$IB,"<3>",BI=3$,$IB,"<4>",BI=4$,$IB,"<5>",BI=5$};
|
|
|
|
|
|
|
|
|
|
$SP,"<6>",BI=6$
|
|
|
|
|
|
|
|
|
|
$SP,"<7>",BI=7$
|
|
|
|
|
|
|
|
|
|
$SP,"<8>",BI=8$
|
|
|
|
|
|
|
|
|
|
U8 *friendly_hacking_imgs[4]={$IB,"<7>",BI=7$,$IB,"<6>",BI=6$,$IB,"<7>",BI=7$,$IB,"<8>",BI=8$};
|
|
|
|
|
|
|
|
|
|
$SP,"<9>",BI=9$
|
|
|
|
|
|
|
|
$SP,"<10>",BI=10$
|
|
|
|
|
|
|
|
$SP,"<11>",BI=11$
|
|
|
|
|
|
|
|
U8 *enemy_imgs[4]={$IB,"<10>",BI=10$,$IB,"<9>",BI=9$,$IB,"<10>",BI=10$,$IB,"<11>",BI=11$};
|
|
|
|
|
|
|
|
|
|
$SP,"<12>",BI=12$
|
|
|
|
|
|
|
|
|
|
$SP,"<13>",BI=13$
|
|
|
|
|
|
|
|
|
|
$SP,"<14>",BI=14$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"<15>",BI=15$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
U8 *enemy_hacking_imgs[4]={$IB,"<13>",BI=13$,$IB,"<12>",BI=12$,$IB,"<13>",BI=13$,$IB,"<14>",BI=14$};
|
|
|
|
|
|
#define LANDSCAPE_TYPES 4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"<16>",BI=16$
|
|
|
|
|
|
|
|
|
|
$SP,"<17>",BI=17$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"<18>",BI=18$
|
|
|
|
|
|
|
|
|
|
|
|
$SP,"<19>",BI=19$
|
|
|
|
|
|
|
|
$BG$
|
|
|
|
U8 *landscape_imgs[LANDSCAPE_TYPES]=
|
|
{$IB,"<16>",BI=16$,$IB,"<17>",BI=17$,$IB,"<18>",BI=18$,$IB,"<19>",BI=19$};
|
|
|
|
#define MAX_LANDSCAPE 128
|
|
class LandScapeItem
|
|
{
|
|
I64 x,y;
|
|
U8 *img;
|
|
} ls[MAX_LANDSCAPE];
|
|
|
|
U0 Explosion(CDC *dc,I64 num,I64 y)
|
|
{
|
|
Unit *tmpu=&u[num];
|
|
I64 i,n1,n2,n3,n4,n5;
|
|
F64 t=(tS-tmpu->die_time)/(tmpu->corpse_timeout-tmpu->die_time);
|
|
Seed(num+1);
|
|
if (tmpu->missile_strike) {
|
|
n1=128; n2=30; n3=30; n4=99; n5=99;
|
|
} else if (tmpu->tank) {
|
|
n1=64; n2=14; n3=12; n4=60; n5=45;
|
|
} else {
|
|
n1=8; n2=0; n3=0; n4=18; n5=14;
|
|
}
|
|
for (i=0;i<n1;i++) {
|
|
if (tmpu->missile_strike && i&2) {
|
|
if (i&1) {
|
|
if (i&4)
|
|
dc->color=RED;
|
|
else
|
|
dc->color=DKGRAY;
|
|
} else
|
|
dc->color=YELLOW;
|
|
} else if (tmpu->tank && i&2) {
|
|
if (i&1) {
|
|
if (i&4)
|
|
dc->color=RED;
|
|
else
|
|
dc->color=RED;
|
|
} else
|
|
dc->color=LTRED;
|
|
} else if (i&1)
|
|
dc->color=WHITE;
|
|
else
|
|
dc->color=LTGRAY;
|
|
GrLine(dc,tmpu->x+n2*(Rand-.5),y+n3*Rand,
|
|
tmpu->x+n4*t*(Rand-.5),y-n5*t*Rand);
|
|
}
|
|
}
|
|
|
|
I64 mp_not_done_flags;
|
|
U0 MPDrawMen(CDC *dc2)
|
|
{
|
|
CTask *task=dc2->win_task;
|
|
CDC *dc=DCAlias(dc2,task);
|
|
I64 i,r[16],lo=Gs->num*MAX_UNIT/mp_cnt,hi=(Gs->num+1)*MAX_UNIT/mp_cnt,
|
|
yy,phase,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
|
Unit *tmpu;
|
|
U8 *tmps,**_tmps;
|
|
F64 tt,ts=tS;
|
|
|
|
for (i=lo;i<hi;i++) {
|
|
tmpu=&u[i];
|
|
yy=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
|
|
if (-32<=yy<=task->pix_bottom+32) {
|
|
if (tmpu->dead) {
|
|
if (tmpu->corpse_timeout) {
|
|
Explosion(dc,i,yy);
|
|
if (tS>tmpu->corpse_timeout)
|
|
tmpu->corpse_timeout=0;
|
|
}
|
|
} else {
|
|
Mat4x4IdentEqu(r);
|
|
Mat4x4RotY(r,tmpu->é+ã/2);
|
|
Mat4x4RotX(r,ã/6);
|
|
Mat4x4Scale(r,0.3);
|
|
if (tmpu->tank)
|
|
SpriteMat3B(dc,tmpu->x,yy,GR_Z_ALL,$IB,"<15>",BI=15$,r);
|
|
else {
|
|
if (tmpu->best_dd<(2*HACK_DIST)*(2*HACK_DIST)) {//It's neat so times 2
|
|
if (tmpu->friendly)
|
|
_tmps=friendly_hacking_imgs;
|
|
else
|
|
_tmps=enemy_hacking_imgs;
|
|
tt=4*Wrap(tmpu->phase+20*ts,0)/(2*ã);
|
|
} else {
|
|
if (tmpu->friendly)
|
|
_tmps=friendly_imgs;
|
|
else
|
|
_tmps=enemy_imgs;
|
|
tt=4*Wrap(tmpu->phase+5*ts,0)/(2*ã);
|
|
}
|
|
phase=tt; tt%=1.0;
|
|
tmps=SpriteInterpolate(tt,_tmps[phase&3],_tmps[(phase+1)&3]);
|
|
SpriteMat3B(dc,tmpu->x,yy,GR_Z_ALL,tmps,r);
|
|
Free(tmps);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dc->depth_buf=NULL;
|
|
DCDel(dc);
|
|
LBtr(&mp_not_done_flags,Gs->num);
|
|
Seed; //Return Seth task to timer-based.
|
|
}
|
|
|
|
U0 DrawIt(CTask *task,CDC *dc)
|
|
{
|
|
I64 i,yy,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
|
F64 tt,ts=tS;
|
|
Bullet *tmpb;
|
|
|
|
dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
|
|
GrRect3(dc,0,0,0,dc->width,dc->height);
|
|
|
|
for (i=0;i<MAX_LANDSCAPE;i++) {
|
|
yy=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
|
|
if (-32<=yy<=task->pix_bottom+32)
|
|
Sprite3(dc,ls[i].x,yy,0,ls[i].img);
|
|
}
|
|
|
|
dc->pen_width=3;
|
|
dc->color=BROWN;
|
|
GrLine3(dc,0, (finish_line-scroll_y)&(MAP_HEIGHT-1),0,
|
|
GR_WIDTH,(finish_line-scroll_y)&(MAP_HEIGHT-1),0);
|
|
|
|
dc->color=LTGRAY;
|
|
for (i=0,tmpb=b;i<MAX_BULLETS;i++,tmpb++)
|
|
if (!tmpb->dead) {
|
|
if (tmpb->missile)
|
|
SpriteZ3B(dc,tmpb->x>>32,tmpb->y>>32,0,$IB,"<2>",BI=2$,Arg(tmpb->dx,tmpb->dy));
|
|
else
|
|
GrLine(dc,tmpb->x>>32,tmpb->y>>32,
|
|
(tmpb->x+tmpb->dx*BULLET_LEN)>>32,
|
|
(tmpb->y+tmpb->dy*BULLET_LEN)>>32);
|
|
}
|
|
|
|
DCDepthBufAlloc(dc);
|
|
mp_not_done_flags=1<<mp_cnt-1;
|
|
for (i=0;i<mp_cnt;i++)
|
|
JobQue(&MPDrawMen,dc,i);
|
|
while (mp_not_done_flags)
|
|
Yield;
|
|
Free(dc->depth_buf);
|
|
dc->depth_buf=NULL;
|
|
|
|
SpriteZ3B(dc,x,y,0,$IB,"<1>",BI=1$,é);
|
|
|
|
if (tf) {
|
|
tt=tf;
|
|
dc->color=RED;
|
|
if (game_over && Blink)
|
|
GrPrint(dc,task->pix_width/2-9*FONT_WIDTH/2,task->pix_height/2,
|
|
"Game Over");
|
|
} else {
|
|
tt=ts;
|
|
if (!enemy_left || !friendly_left)
|
|
game_over=TRUE;
|
|
}
|
|
dc->color=BLACK;
|
|
GrPrint(dc,0,0,"Enemy:%d Friends:%d Friendly Fire:%d Time:%6.2f "
|
|
"Bullets:%d Missiles:%d",enemy_left,friendly_left,friendly_fire,
|
|
tt-t0,bullets_fired,missiles_fired);
|
|
GrPrint(dc,0,8,"Total Score:%,d High Score:%,d",
|
|
total_score,best_score);
|
|
}
|
|
|
|
U0 ManDie(Unit *tmpu,Bool by_human)
|
|
{
|
|
tmpu->dead=TRUE;
|
|
tmpu->die_time=tS;
|
|
if (by_human) {
|
|
if (tmpu->missile_strike)
|
|
tmpu->corpse_timeout=tS+1.0;
|
|
else if (tmpu->tank)
|
|
tmpu->corpse_timeout=tS+0.40;
|
|
else
|
|
tmpu->corpse_timeout=tS+0.20;
|
|
} else
|
|
tmpu->corpse_timeout=0;
|
|
|
|
if (tmpu->friendly) {
|
|
friendly_left--;
|
|
if (by_human)
|
|
friendly_fire++;
|
|
} else {
|
|
enemy_left--;
|
|
if (!by_human)
|
|
enemy_by_friendly++;
|
|
}
|
|
if (by_human && !snd_timeout) {
|
|
snd_timeout=tS+0.01;
|
|
if (tmpu->friendly)
|
|
Snd(200);
|
|
else
|
|
Snd(50);
|
|
}
|
|
}
|
|
|
|
U0 CheckCollisions()
|
|
{
|
|
I64 i,i2,x,y,x2,y2,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
|
|
Unit *tmpu,*tmpu2;
|
|
Bullet *tmpb;
|
|
CDC *dc2=DCNew(GR_WIDTH,GR_HEIGHT);
|
|
dc2->color=LTRED;
|
|
for (i=0,tmpb=b;i<MAX_BULLETS;i++,tmpb++)
|
|
if (!tmpb->dead && !tmpb->missile) //Bullets not missiles
|
|
GrLine(dc2,tmpb->x>>32,tmpb->y>>32,
|
|
(tmpb->x+tmpb->dx*BULLET_LEN)>>32,
|
|
(tmpb->y+tmpb->dy*BULLET_LEN)>>32);
|
|
|
|
dc2->color =ROP_COLLISION;
|
|
dc2->bkcolor=BLACK;
|
|
for (i=0,tmpu=u;i<MAX_UNIT;i++,tmpu++) {
|
|
if (!tmpu->dead) {
|
|
x=tmpu->x;
|
|
y=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
|
|
if (0<=x<GR_WIDTH && 0<=y<GR_HEIGHT) {
|
|
dc2->collision_cnt=0;
|
|
GrRect(dc2,x-3,y-9,6,8);
|
|
if (dc2->collision_cnt)
|
|
ManDie(tmpu,TRUE);
|
|
}
|
|
}
|
|
}
|
|
DCDel(dc2);
|
|
|
|
for (i=0,tmpb=b;i<MAX_BULLETS;i++,tmpb++)
|
|
if (!tmpb->dead && tmpb->missile) { //Missiles not bullets
|
|
x=tmpb->x>>32;
|
|
y=tmpb->y>>32;
|
|
for (i=0,tmpu=u;i<MAX_UNIT;i++,tmpu++) {
|
|
if (!tmpu->dead && AbsI64(x-tmpu->x-3)+
|
|
AbsI64(y-(tmpu->y-scroll_y)&(MAP_HEIGHT-1)+2)<7+14*tmpu->tank) {
|
|
tmpb->dead=TRUE;
|
|
tmpu->missile_strike=TRUE;
|
|
ManDie(tmpu,TRUE);
|
|
for (i2=0,tmpu2=u;i2<MAX_UNIT;i2++,tmpu2++) {
|
|
if (!tmpu2->dead) {
|
|
x2=tmpu2->x;
|
|
y2=(tmpu2->y-scroll_y)&(MAP_HEIGHT-1);
|
|
if (SqrI64(x-x2)+SqrI64(y-y2)<100*100)
|
|
ManDie(tmpu2,TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
U0 Init()
|
|
{
|
|
I64 i,xx,yy,scroll_y=MAP_HEIGHT-100;
|
|
Unit *tmpu;
|
|
|
|
snd_timeout=0;
|
|
Snd(0);
|
|
|
|
total_score=0;
|
|
game_over=FALSE;
|
|
main_loop_pass=0;
|
|
|
|
x=Fs->pix_width>>1;
|
|
y=0.9*Fs->pix_height;
|
|
finish_line=scroll_y+y;
|
|
dx=0;
|
|
dy=0;
|
|
é=0;
|
|
|
|
for (i=0;i<MAX_LANDSCAPE;i++) {
|
|
ls[i].x=(Fs->pix_width-100)*RandU32/MAX_U32+50;
|
|
ls[i].y=(MAP_HEIGHT-100)*RandU32/MAX_U32+50;
|
|
ls[i].img=landscape_imgs[RandU16%(LANDSCAPE_TYPES-2)];
|
|
}
|
|
|
|
for (i=0;i<2;i++)
|
|
ls[i].img=landscape_imgs[LANDSCAPE_TYPES-2]; //mountain
|
|
|
|
for (;i<20;i++)
|
|
ls[i].img=landscape_imgs[LANDSCAPE_TYPES-1]; //Apartment
|
|
|
|
MemSet(u,0,sizeof(u));
|
|
for (i=0,tmpu=u;i<MAX_UNIT;i++,tmpu++) {
|
|
if (i<MAX_FRIENDLY) {
|
|
tmpu->friendly=TRUE;
|
|
if (!(i&7)) {
|
|
xx=(Fs->pix_width-200)*RandU32/MAX_U32;
|
|
yy=(MAP_HEIGHT-200)*RandU32/MAX_U32;
|
|
}
|
|
} else {
|
|
tmpu->friendly=FALSE;
|
|
if (!(i&31)) {
|
|
xx=(Fs->pix_width-200)*RandU32/MAX_U32;
|
|
yy=(MAP_HEIGHT-200)*RandU32/MAX_U32;
|
|
}
|
|
if (!(i&15))
|
|
tmpu->tank=TRUE;
|
|
}
|
|
tmpu->dead=FALSE;
|
|
tmpu->missile_strike=FALSE;
|
|
tmpu->x=xx+64*RandI32/MAX_I32+100;
|
|
tmpu->y=yy+64*RandU32/MAX_I32-64+100;
|
|
tmpu->best_dd=MAX_I64;
|
|
tmpu->é=0;
|
|
tmpu->phase=2*ã*Rand;
|
|
tmpu->corpse_timeout=0;
|
|
}
|
|
for (i=0;i<MAX_BULLETS;i++)
|
|
b[i].dead=TRUE;
|
|
friendly_left=MAX_FRIENDLY;
|
|
enemy_left =MAX_ENEMY;
|
|
enemy_by_friendly=0;
|
|
bullets_fired=0;
|
|
missiles_fired=0;
|
|
friendly_fire=0;
|
|
t0=tS;
|
|
tf=0;
|
|
}
|
|
|
|
U0 FireBullet()
|
|
{
|
|
I64 i,j;
|
|
F64 a;
|
|
Bullet *tmpb;
|
|
for (i=0;i<MAX_BULLETS-1;i++)
|
|
if (b[i].dead)
|
|
break;
|
|
tmpb=&b[i];
|
|
|
|
j=x+28.0*Sin(é);
|
|
tmpb->x=j<<32;
|
|
|
|
j=y-28.0*Cos(é);
|
|
tmpb->y=j<<32;
|
|
|
|
tmpb->dx2=(BULLET_SPEED*Sin(é)+dx)*0x100000000;
|
|
tmpb->dy2=-BULLET_SPEED*Cos(é)*0x100000000;
|
|
a=Arg(tmpb->dx2,tmpb->dy2);
|
|
tmpb->dx=Cos(a)*0x100000000;
|
|
tmpb->dy=Sin(a)*0x100000000;
|
|
bullets_fired++;
|
|
tmpb->dead=FALSE;
|
|
tmpb->missile=FALSE;
|
|
if (!snd_timeout) {
|
|
snd_timeout=tS+0.0005;
|
|
Snd(1000);
|
|
}
|
|
}
|
|
|
|
U0 FireMissile(I64 n)
|
|
{
|
|
I64 i,j;
|
|
F64 a;
|
|
Bullet *tmpb;
|
|
for (i=0;i<MAX_BULLETS-1;i++)
|
|
if (b[i].dead)
|
|
break;
|
|
tmpb=&b[i];
|
|
|
|
j=x-10.0*Sin(é)+20.0*Sin(é+n*ã/2);
|
|
tmpb->x=j<<32;
|
|
|
|
j=y+10.0*Cos(é)-20.0*Cos(é+n*ã/2);
|
|
tmpb->y=j<<32;
|
|
|
|
tmpb->dx2=(BULLET_SPEED*Sin(é)+dx)*0x100000000;
|
|
tmpb->dy2=-BULLET_SPEED*Cos(é)*0x100000000;
|
|
a=Arg(tmpb->dx2,tmpb->dy2);
|
|
tmpb->dx=Cos(a)*0x100000000;
|
|
tmpb->dy=Sin(a)*0x100000000;
|
|
missiles_fired++;
|
|
tmpb->dead=FALSE;
|
|
tmpb->missile=TRUE;
|
|
if (!snd_timeout) {
|
|
snd_timeout=tS+0.0005;
|
|
Snd(1000);
|
|
}
|
|
}
|
|
|
|
U0 MenMove(I64 phase_group)
|
|
{
|
|
I64 i,j,dd,best,best_dd;
|
|
for (i=phase_group;i<MAX_FRIENDLY;i+=PHASES_GROUPS) {
|
|
if (!u[i].dead) {
|
|
best=MAX_FRIENDLY;
|
|
best_dd=MAX_I64;
|
|
for (j=MAX_FRIENDLY;j<MAX_UNIT;j++) {
|
|
if (!u[j].dead) {
|
|
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
|
if (dd<best_dd) {
|
|
best_dd=dd;
|
|
best=j;
|
|
}
|
|
}
|
|
}
|
|
u[i].best_dd=best_dd;
|
|
if (best_dd!=MAX_I64) {
|
|
u[i].x+=4*SignI64(u[best].x-u[i].x);
|
|
u[i].y+=4*SignI64(u[best].y-u[i].y);
|
|
u[i].é=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
|
|
}
|
|
}
|
|
}
|
|
for (i=MAX_FRIENDLY+phase_group;i<MAX_UNIT;i+=PHASES_GROUPS) {
|
|
if (!u[i].dead) {
|
|
best=0;
|
|
best_dd=MAX_I64;
|
|
for (j=0;j<MAX_FRIENDLY;j++) {
|
|
if (!u[j].dead) {
|
|
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
|
if (dd<best_dd) {
|
|
best_dd=dd;
|
|
best=j;
|
|
}
|
|
}
|
|
}
|
|
u[i].best_dd=best_dd;
|
|
if (best_dd!=MAX_I64) {
|
|
u[i].x+=4*SignI64(u[best].x-u[i].x);
|
|
u[i].y+=4*SignI64(u[best].y-u[i].y);
|
|
u[i].é=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
U0 MenFight(I64 phase_group)
|
|
{
|
|
I64 i,j,dd,best,best_dd;
|
|
for (i=phase_group;i<MAX_FRIENDLY;i+=PHASES_GROUPS) {
|
|
if (!u[i].dead) {
|
|
best=MAX_FRIENDLY;
|
|
best_dd=MAX_I64;
|
|
for (j=MAX_FRIENDLY;j<MAX_UNIT;j++) {
|
|
if (!u[j].dead && u[i].y-u[j].y<8) {
|
|
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
|
if (dd<best_dd) {
|
|
best_dd=dd;
|
|
best=j;
|
|
}
|
|
}
|
|
}
|
|
u[i].best_dd=best_dd;
|
|
if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
|
|
ManDie(&u[best],FALSE);
|
|
}
|
|
}
|
|
for (i=MAX_FRIENDLY+phase_group;i<MAX_UNIT;i+=PHASES_GROUPS) {
|
|
if (!u[i].dead) {
|
|
best=0;
|
|
best_dd=MAX_I64;
|
|
for (j=0;j<MAX_FRIENDLY;j++) {
|
|
if (!u[j].dead&& u[i].y-u[j].y<8) {
|
|
dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
|
|
if (dd<best_dd) {
|
|
best_dd=dd;
|
|
best=j;
|
|
}
|
|
}
|
|
}
|
|
u[i].best_dd=best_dd;
|
|
if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
|
|
ManDie(&u[best],FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
U0 TimeOut()
|
|
{
|
|
I64 i,msg_code,ch,sc;
|
|
Bool gun_on;
|
|
|
|
I64 next_update_jiffy;
|
|
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
|
|
|
MenuPush(
|
|
"File {"
|
|
" Abort(,CH_SHIFT_ESC);"
|
|
" Exit(,CH_ESC);"
|
|
"}"
|
|
"Play {"
|
|
" Restart(,'\n');"
|
|
" Fire(,CH_SPACE);"
|
|
" Left(,,SC_CURSOR_LEFT);"
|
|
" Right(,,SC_CURSOR_RIGHT);"
|
|
" LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
|
|
" RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
|
|
"}"
|
|
);
|
|
AutoComplete;
|
|
WinBorder;
|
|
WinMax;
|
|
DocCursor;
|
|
DocClear;
|
|
|
|
"\nScoring:\n"
|
|
"\tEnemy Killed\t\t+3\n"
|
|
"\tEnemy by Friendly\t+5\n"
|
|
"\tFriendly Fire\t\t-100\n"
|
|
"\tBullets Fired\t\t-1\n"
|
|
"\tMissiles Fired\t\t-50\n"
|
|
"\tGame Time\t\t-10 per second\n"
|
|
"\tSurviving Friendlies\t+250\n\n"
|
|
"Sweep side-to-side while shooting, "
|
|
"holding down $$GREEN$$<SPACE>$$FG$$.\n\n";
|
|
PressAKey;
|
|
|
|
Init;
|
|
DocClear;
|
|
Fs->draw_it=&DrawIt;
|
|
|
|
gun_on=FALSE;
|
|
|
|
try {
|
|
while (TRUE) {
|
|
next_update_jiffy=cnts.jiffies+JIFFY_FREQ/100;
|
|
while (msg_code=ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
|
|
switch (msg_code) {
|
|
case MSG_KEY_DOWN:
|
|
switch (ch) {
|
|
case 0:
|
|
switch (sc.u8[0]) {
|
|
case SC_CURSOR_RIGHT:
|
|
if (sc&SCF_CTRL)
|
|
FireMissile(1);
|
|
break;
|
|
case SC_CURSOR_LEFT:
|
|
if (sc&SCF_CTRL)
|
|
FireMissile(-1);
|
|
break;
|
|
}
|
|
break;
|
|
case CH_SHIFT_ESC:
|
|
case CH_ESC:
|
|
goto to_done;
|
|
case '\n':
|
|
Init;
|
|
break;
|
|
case CH_SPACE:
|
|
gun_on=TRUE;
|
|
break;
|
|
}
|
|
break;
|
|
case MSG_KEY_UP:
|
|
if (ch==CH_SPACE)
|
|
gun_on=FALSE;
|
|
else if (sc.u8[0]==SC_CURSOR_RIGHT||sc.u8[0]==SC_CURSOR_LEFT)
|
|
é=0.0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (i=0;i<MAX_BULLETS;i++) {
|
|
if (!b[i].dead) {
|
|
b[i].x+=b[i].dx2;
|
|
b[i].y+=b[i].dy2;
|
|
if (b[i].y<0||b[i].x<0||
|
|
b[i].x>>32>=Fs->pix_width||
|
|
b[i].y>>32>=Fs->pix_height)
|
|
b[i].dead=TRUE;
|
|
}
|
|
}
|
|
|
|
dx=0;
|
|
if (!Bt(kbd.down_bitmap,SC_CTRL)) {
|
|
if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
|
|
é=-15.0*ã/180.0;
|
|
dx=-2;
|
|
} else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
|
|
é=15.0*ã/180.0;
|
|
dx=2;
|
|
}
|
|
}
|
|
x+=dx;
|
|
while (x>=Fs->pix_width)
|
|
x-=Fs->pix_width;
|
|
while (x<0)
|
|
x+=Fs->pix_width;
|
|
|
|
//It takes too much CPU do do all these all the time.
|
|
switch [main_loop_pass&7] {
|
|
case 0:
|
|
switch [main_loop_pass>>3&7] {
|
|
case 0:
|
|
if (--y<20)
|
|
game_over=TRUE;
|
|
case 2:
|
|
case 4:
|
|
case 6:
|
|
MenFight(main_loop_pass>>4%PHASES_GROUPS);
|
|
break;
|
|
case 1:
|
|
case 3:
|
|
case 5:
|
|
case 7:
|
|
MenMove (main_loop_pass>>4%PHASES_GROUPS);
|
|
break;
|
|
}
|
|
case 4:
|
|
break;
|
|
case 2:
|
|
case 6:
|
|
if (gun_on)
|
|
FireBullet;
|
|
break;
|
|
case 1:
|
|
case 3:
|
|
case 5:
|
|
case 7:
|
|
CheckCollisions;
|
|
break;
|
|
}
|
|
main_loop_pass++;
|
|
|
|
if (snd_timeout && tS>snd_timeout) {
|
|
snd_timeout=0;
|
|
Snd(0);
|
|
}
|
|
SleepUntil(next_update_jiffy);
|
|
|
|
total_score=3*(MAX_ENEMY-enemy_left)+5*enemy_by_friendly
|
|
-100*friendly_fire-10*(tS-t0)-bullets_fired-50*missiles_fired;
|
|
if (game_over) {
|
|
tf=tS;
|
|
Sleep(750);
|
|
FlushMsgs;
|
|
while (!ScanKey(&ch)&&friendly_left) {
|
|
total_score+=250;
|
|
Snd(2000); Sleep(150);
|
|
Snd(0); Sleep(50);
|
|
friendly_left--;
|
|
}
|
|
total_score+=250*friendly_left;
|
|
if (total_score>best_score)
|
|
best_score=total_score;
|
|
if (!ch) ch=GetChar(,FALSE);
|
|
if (ch==CH_ESC||ch==CH_SHIFT_ESC)
|
|
goto to_done;
|
|
gun_on=FALSE;
|
|
Init;
|
|
}
|
|
}
|
|
to_done:
|
|
GetMsg(,,1<<MSG_KEY_UP);
|
|
}
|
|
catch
|
|
PutExcept;
|
|
SettingsPop;
|
|
MenuPop;
|
|
RegWriteBranch("TempleOS/TimeOut","I64 best_score=%d;\n",best_score);
|
|
}
|
|
|