ZealOS/src/Demo/Games/DunGen.ZC
2023-11-12 10:40:40 -05:00

621 lines
No EOL
21 KiB
HolyC
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

RegDefault("ZealOS/DunGen", "F64 best_score=9999;\n");
RegExe("ZealOS/DunGen");
//Set snap to 4 and width to 4
//if you edit this map.
//Don't forget to change the
//starting pos.
$BG,0$
$SP,"<1>",BI=1$
$SP,"<2>",BI=2$
$SP,"<3>",BI=3$
$SP,"<4>",BI=4$
$SP,"<5>",BI=5$
$SP,"<6>",BI=6$
$SP,"<7>",BI=7$
$SP,"<8>",BI=8$
$SP,"<9>",BI=9$
$SP,"<10>",BI=10$
$BG$//These are indexed by color #.
//See $LK,"COLORS",A="MN:RED"$.
U8 *tiles1[16]={NULL, $IB,"<7>",BI=7$ , $IB,"<5>",BI=5$ , NULL, NULL, NULL, NULL, NULL, $IB,"<6>",BI=6$ , NULL, NULL, NULL, NULL, NULL, NULL, NULL};
U8 *tiles2[16]={NULL, $IB,"<8>",BI=8$ , $IB,"<5>",BI=5$ , NULL, NULL, NULL, NULL, NULL, $IB,"<6>",BI=6$ , NULL, NULL, NULL, NULL, NULL, NULL, NULL};
#define SCREEN_SCALE 24
#define SCREEN_WIDTH 24
#define SCREEN_HEIGHT 24
I64 screen_x, screen_y;
#define MAP_SCALE 4
I64 map_width, map_height;
U8 *map = NULL;
I64 man_x, man_y, man_dx, man_dy;
Bool man_attack;
F64 man_attack_t0;
#define MONSTERS_NUM 10
I64 monsters_left;
class Monster
{
I64 x, y, dx, dy;
Bool dead, pad[7];
} monsters[MONSTERS_NUM];
F64 t0, tf;
#define LOS_SCALE 4
Bool LOSPlot(U8 *, I64 x, I64 y, I64)
{
if (!map[(y / LOS_SCALE) * map_width + (x / LOS_SCALE)])
return FALSE;
else
return TRUE;
}
Bool LOS(I64 x1, I64 y1, I64 x2, I64 y2)
{//Line of sight
return Line(NULL, x1 * LOS_SCALE + LOS_SCALE / 2, y1 * LOS_SCALE + LOS_SCALE / 2, 0,
x2 * LOS_SCALE + LOS_SCALE / 2, y2 * LOS_SCALE + LOS_SCALE / 2, 0, &LOSPlot);
}
U0 DrawIt(CTask *task, CDC *dc)
{
CDC *dc_t = DCAlias(gr.dc2, task);
I64 i, x, y, xx, yy, x1, y1, z1, color,
cx = task->pix_width / 2,
cy = task->pix_height / 2;
CD3I32 poly[4];
U8 **_tiles;
F64 tt;
Monster *tmpm;
if (Blink(5))
_tiles = tiles1;
else
_tiles = tiles2;
Mat4x4RotX(dc_t->r, 60 * 2 * π / 360);
Mat4x4RotZ(dc_t->r, 15 * 2 * π / 360);
DCMat4x4Set(dc_t, dc_t->r);
dc_t->x = task->pix_width / 2;
dc_t->y = task->pix_height / 2;
dc_t->flags |= DCF_TRANSFORMATION;
//You could make it much more efficient
//if you did it like $LK,"::/Demo/Games/BigGuns.ZC"$
//with a $LK,"CDC",A="MN:CDC"$.
for (y = -SCREEN_HEIGHT / 2; y < SCREEN_HEIGHT / 2; y++)
{
yy = y + screen_y;
if (0 <= yy < map_height)
for (x = -SCREEN_WIDTH / 2; x < SCREEN_WIDTH / 2; x++)
{
xx = x + screen_x;
if (0 <= xx < map_width)
{
if ((color = map[yy * map_width + xx]) && LOS(xx, yy, man_x, man_y))
{
if (_tiles[color])
{
x1 = x * SCREEN_SCALE;
y1 = y * SCREEN_SCALE;
z1 = 0;
DCTransform(dc_t, &x1, &y1, &z1);
Sprite3(dc, x1, y1, z1, _tiles[color]);
}
else
{//If no tile defined, do solid color.
poly[0].x = x * SCREEN_SCALE;
poly[0].y = y * SCREEN_SCALE;
poly[0].z = 0;
poly[1].x = (x + 1) * SCREEN_SCALE - 1;
poly[1].y = y * SCREEN_SCALE;
poly[1].z = 0;
poly[2].x = (x + 1) * SCREEN_SCALE;
poly[2].y = (y + 1) * SCREEN_SCALE - 1;
poly[2].z = 0;
poly[3].x = x * SCREEN_SCALE - 1;
poly[3].y = (y + 1) * SCREEN_SCALE - 1;
poly[3].z = 0;
dc_t->color = color;
GrFillPoly3(dc_t, 4, poly);
}
}
}
}
}
for (y = -SCREEN_HEIGHT / 2; y < SCREEN_HEIGHT / 2; y++)
{
yy = y + screen_y;
if (0 <= yy < map_height)
for (x = -SCREEN_WIDTH / 2; x < SCREEN_WIDTH / 2; x++)
{
xx = x + screen_x;
if (0 <= xx < map_width)
{
if (!map[yy * map_width + xx])
{
if (yy + 1 < map_height && LOS(xx, yy + 1, man_x, man_y))
{
x1 = x * SCREEN_SCALE;
y1 = y * SCREEN_SCALE;
z1 = 0;
DCTransform(dc_t, &x1, &y1, &z1);
Sprite3(dc, x1, y1, z1, $IB,"<9>",BI=9$);
}
if (xx + 1 < map_width && LOS(xx + 1, yy, man_x, man_y))
{
x1 = x * SCREEN_SCALE;
y1 = y * SCREEN_SCALE;
z1 = 0;
DCTransform(dc_t, &x1, &y1, &z1);
Sprite3(dc, x1, y1, z1, $IB,"<10>",BI=10$);
}
}
}
}
}
for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++)
if (!tmpm->dead && LOS(tmpm->x, tmpm->y, man_x, man_y))
{
x1 = (tmpm->x - screen_x) * SCREEN_SCALE + SCREEN_SCALE / 2;
y1 = (tmpm->y - screen_y) * SCREEN_SCALE + SCREEN_SCALE / 2;
z1 = 0;
DCTransform(dc_t, &x1, &y1, &z1);
if (tmpm->dx < 0) {
dc->flags |= DCF_SYMMETRY|DCF_JUST_MIRROR;
DCSymmetrySet(dc, x1, y1, x1, y1 + 1);
}
else
dc->flags &= ~(DCF_SYMMETRY | DCF_JUST_MIRROR);
Sprite3(dc, x1, y1, z1, $IB,"<4>",BI=4$);
}
x1 = (man_x - screen_x) * SCREEN_SCALE + SCREEN_SCALE / 2;
y1 = (man_y - screen_y) * SCREEN_SCALE + SCREEN_SCALE / 2;
z1 = 0;
if (tS - man_attack_t0 < 0.2)
{
x1 += Tri(tS - man_attack_t0, 0.2) * SCREEN_SCALE * man_dx;
y1 += Tri(tS - man_attack_t0, 0.2) * SCREEN_SCALE * man_dy;
if (man_dy != 1)
y1 -= Saw(tS - man_attack_t0, 0.2) * SCREEN_SCALE;
}
DCTransform(dc_t, &x1, &y1, &z1);
if (man_dx < 0)
{
dc->flags |= DCF_SYMMETRY | DCF_JUST_MIRROR;
DCSymmetrySet(dc, x1, y1, x1, y1 + 1);
}
else
dc->flags &= ~(DCF_SYMMETRY | DCF_JUST_MIRROR);
if (tS - man_attack_t0 < 0.2)
Sprite3(dc, x1, y1, z1, $IB,"<3>",BI=3$);
else
Sprite3(dc, x1, y1, z1, $IB,"<2>",BI=2$);
DCDel(dc_t);
if (tf)
{
dc->color = LTRED;
if (Blink)
GrPrint(dc, cx - (FONT_WIDTH * 14) / 2, cy - FONT_HEIGHT / 2, "Game Completed");
tt = tf;
}
else
{
dc->color = LTGREEN;
tt = tS;
}
GrPrint(dc, 0, 0, "Enemy:%d Time:%3.2f Best:%3.2f", monsters_left, tt - t0, best_score);
}
U0 Attack()
{
I64 i;
Monster *tmpm;
man_attack_t0 = tS;
Noise(100, 53, 74);
for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++)
{
if (!tmpm->dead && man_x + man_dx == tmpm->x && man_y + man_dy == tmpm->y)
{
tmpm->dead = TRUE;
if (!--monsters_left)
{
tf = tS;
if (tf - t0 < best_score)
best_score = tf - t0;
}
}
}
}
U0 Init()
{
I64 i, x, y;
CDC *dc;
Monster *tmpm;
dc = Sprite2DC($IB,"<1>",BI=1$);
map_width = dc->width / MAP_SCALE;
map_height = dc->height / MAP_SCALE;
Free(map);
map = MAlloc(map_width * map_height * sizeof(U8));
for (y = 0; y < map_height; y++)
for (x = 0; x < map_width; x++)
map[y * map_width + x] = GrPeek(dc, x * MAP_SCALE, y * MAP_SCALE);
DCDel(dc);
man_attack_t0 = 0;
man_attack = FALSE;
man_x = 0;
man_y = 4;
man_dx = 0;
man_dy = 0;
screen_x = 0;
screen_y = 0;
for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++)
{
tmpm->dead = FALSE;
tmpm->dx = 0;
tmpm->dy = 0;
do
{
tmpm->x = RandU64 % (map_width - 2) + 1;
tmpm->y = RandU64 % (map_height - 2) + 1;
}
while (!map[(tmpm->y) * map_width + tmpm->x]);
}
monsters_left = MONSTERS_NUM;
tf = 0;
t0 = tS;
}
U0 CleanUp()
{
Free(map);
map = NULL;
}
U0 AnimateTask(I64)
{
I64 i, x, y, dx, dy;
Monster *tmpm;
while (TRUE)
{
for (i = 0, tmpm = monsters; i < MONSTERS_NUM; i++, tmpm++)
if (!tmpm->dead)
{
dx = RandU16 % 3 - 1;
dy = RandU16 % 3 - 1;
x = tmpm->x + dx;
y = tmpm->y + dy;
if (0 <= x < map_width && 0 <= y < map_height && map[y * map_width + x])
{
tmpm->x = x;
tmpm->y = y;
tmpm->dx = dx;
tmpm->dy = dy;
}
}
Sleep(1000);
}
}
U0 DunGen()
{
I64 ch, sc;
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Play {"
" Restart(,'\n');"
" Up(,,SC_CURSOR_UP);"
" Down(,,SC_CURSOR_DOWN);"
" Left(,,SC_CURSOR_LEFT);"
" Right(,,SC_CURSOR_RIGHT);"
" Attack(,CH_SPACE);"
"}"
);
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
Fs->text_attr = BLACK << 4 + WHITE;
AutoComplete;
WinBorder;
WinMax;
DocCursor;
DocClear;
Init;
PaletteSetLight(FALSE);
Fs->animate_task = Spawn(&AnimateTask, NULL, "Animate",, Fs);
Fs->draw_it = &DrawIt;
try
{
while (TRUE)
{
switch (MessageGet(&ch, &sc, 1 << MESSAGE_KEY_DOWN | 1 << MESSAGE_KEY_UP))
{
case MESSAGE_KEY_DOWN:
switch (ch)
{
case '\n':
Init;
break;
case CH_SPACE:
man_attack = TRUE;
break;
case CH_ESC:
case CH_SHIFT_ESC:
goto dg_done;
case 0:
switch (sc.u8[0])
{
case SC_CURSOR_RIGHT:
if (man_attack)
{
man_dx = 1;
man_dy = 0;
Attack;
}
else
if (man_x + 1 < map_width && map[man_y * map_width + (man_x + 1)] == DKGRAY)
{
man_x++;
if (man_x - screen_x > SCREEN_WIDTH / 2 - 3)
{
screen_x += SCREEN_WIDTH / 2;
if (screen_x + SCREEN_WIDTH / 2 > map_width)
screen_x = map_width - SCREEN_WIDTH / 2;
}
}
break;
case SC_CURSOR_LEFT:
if (man_attack)
{
man_dx = -1;
man_dy = 0;
Attack;
}
else
if (man_x - 1 >= 0 && map[man_y * map_width + (man_x - 1)] == DKGRAY)
{
man_x--;
if (man_x - screen_x < -SCREEN_WIDTH / 2 + 3)
{
screen_x -= SCREEN_WIDTH / 2;
if (screen_x - SCREEN_WIDTH / 2 < 0)
screen_x = SCREEN_WIDTH / 2;
}
}
break;
case SC_CURSOR_UP:
if (man_attack)
{
man_dx = 0;
man_dy = -1;
Attack;
}
else
if (man_y - 1 >= 0 && map[(man_y - 1) * map_width + man_x] == DKGRAY)
{
man_y--;
if (man_y - screen_y < -SCREEN_HEIGHT / 2 + 3)
{
screen_y -= SCREEN_HEIGHT / 2;
if (screen_y - SCREEN_HEIGHT / 2 < 0)
screen_y = SCREEN_HEIGHT / 2;
}
}
break;
case SC_CURSOR_DOWN:
if (man_attack)
{
man_dx = 0;
man_dy = 1;
Attack;
}
else
if (man_y + 1 < map_height && map[(man_y + 1) * map_width + man_x] == DKGRAY)
{
man_y++;
if (man_y - screen_y > SCREEN_HEIGHT / 2 - 3)
{
screen_y += SCREEN_HEIGHT / 2;
if (screen_y + SCREEN_HEIGHT / 2 > map_height)
screen_y = map_height - SCREEN_HEIGHT / 2;
}
}
break;
}
}
break;
case MESSAGE_KEY_UP:
if (ch == CH_SPACE)
man_attack = FALSE;
break;
}
}
dg_done:
MessageGet(,, 1 << MESSAGE_KEY_UP);
}
catch
PutExcept;
SettingsPop;
CleanUp;
MenuPop;
RegWrite("ZealOS/DunGen", "F64 best_score=%5.4f;\n", best_score);
}
DunGen;
ú
7
7   7
7S
SS   
S   7   
CC$
;O
OO
O;
;;
; K
K K
K?
??
?G
C(k(
k(kD
kDCD
CDC,
G,g,
g,g@
g@G@
G@G0
G0c0
c0c<
c<K<
K<K4
K4_4
_4_8
_8O8
k8â8
â,âD
âDƒD
ƒDƒ
ƒù
ùù(
ù(â(
ç,¢,
¢ ¢@
ù@ç@
ç<ç0
ç0ù0
ù0ù<
ù<ï@
ï<ï4
ï4ô4
Å8ô8
ô<Å<
¢¢
¢ï
ç   ç
çs
ss   
s   â   
â   
ââ
âw
ww
w{
{{

ok
gg
gc
cc
?8/8
+0+@
+@@
@0
0'0
'0'<
'<#<
#<#4
787P
3P;P
;P;\
;\3\
3\3T
7T7X
[°   [4
[<[T
[T[\Oc0c<²   δ   &              
                         
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
             
             
              
               
                
                   
                 
                             
             
            
        
                                                                       ²                                                                                                                                                                                                                                                             ²                                                                                                                                                                                                                                                                                                                            ²                                                                                                                                                                                                                                                                                                                                         ²                                                                                                                                                                                                                 
Æ                                                                  2   Φ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             é°   Θ                                                                                                                                                                                                                                                                                                                                                            "∙   ∞