Files

756 lines
19 KiB
Plaintext

uses grafix, jinput, utext, tipos, crt;
procedure FaseNova;forward;
{##############################################################}
{# O F F S E T M A P A #}
{##############################################################}
function OffsetMapa:longint;
var i:longint;
marca : integer;
fich : file of byte;
buffer : byte;
begin
Assign(fich, 'runner.exe');
Reset(fich);
marca := 0;
repeat
Read(fich, buffer);
if buffer = ord('*') then
inc(marca)
else
marca := 0;
inc(i);
until (marca = 10);
OffsetMapa := i;
end;
{##############################################################}
{# C A R R E G A R E C O R D S #}
{##############################################################}
procedure CarregaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
Read(fich, buffer); { centenes }
hi_score := buffer * 100;
Read(fich, buffer); { decenes }
hi_score := score + (buffer * 10);
Read(fich, buffer); { unitats }
hi_score := score + buffer;
Read(fich, buffer); { 1¦ lletra }
nom_hi_score := chr(buffer);
Read(fich, buffer); { 2¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Read(fich, buffer); { 3¦ lletra }
nom_hi_score := nom_hi_score + chr(buffer);
Close(fich);
end;
{##############################################################}
{# G U A R D A R E C O R D S #}
{##############################################################}
procedure GuardaRecords;
var fich : file of byte;
buffer : byte;
begin
Assign(fich, 'records');
Reset(fich);
{Seek(fich, FileSize(fich)-6);}
buffer := score div 100;
Write(fich, buffer); { centenes }
buffer := (score - (buffer*100)) div 10;
Write(fich, buffer); { decenes }
buffer := (score - (buffer*10));
Write(fich, buffer); { unitats }
buffer := ord(nom_hi_score[1]);
Write(fich, buffer); { 1¦ lletra }
buffer := ord(nom_hi_score[2]);
Write(fich, buffer); { 2¦ lletra }
buffer := ord(nom_hi_score[3]);
Write(fich, buffer); { 3¦ lletra }
Close(fich);
end;
{##############################################################}
{# T R A G A P A N T A L L A #}
{##############################################################}
procedure TragaPantalla;
begin
for k:=0 to 23 do
begin
{ despla‡a cap avall }
for i:=0 to 39 do
for j:=23 downto 1 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j-1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j-1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
GotoXY(1,1); TextBackGround(Blue); TextColor(LightGray);
Write('LEVEL ', level:2, ' SCORE ', score:3, ' LIVES ', pepe.vides:1);
GotoXY(13,2);
Write('HI-SCORE ', hi_score:3, ' ', nom_hi_score);
end;
end;
{##############################################################}
{# P O S A R N O M #}
{##############################################################}
procedure PosarNom;
var index : integer;
Key : byte;
Tecla : Pchar;
begin
nom_hi_score := '...';
index := 1;
PutStringCENTERED(13, 15, 'Enhorabona, has');
PutStringCENTERED(14, 15, 'aconseguit un nou record');
PutStringCENTERED(16, 15, nom_hi_score);
repeat
if QTeclaPuls then
begin
Key := AgarrarTecla;
Tecla := nomTECLES[Key];
nom_hi_score[index] := Tecla^;
inc(index);
PutStringCENTERED(16, 15, nom_hi_score);
repeat until not(QTeclaPuls);
end;
until (index = 4);
GuardaRecords;
end;
{##############################################################}
{# G A M E O V E R #}
{##############################################################}
procedure GameOver;
begin
TragaPantalla;
cls($B800);
PutStringCENTERED(10, 15, 'G A M E O V E R');
for i:=0 to 100 do espera_VGA;
if score > hi_score then PosarNom;
FadeDown(0,0,0,0);
end;
{##############################################################}
{# F I N A L P A N T A L L A #}
{##############################################################}
procedure FinalPantalla;
begin
TragaPantalla;
FaseNova;
end;
{##############################################################}
{# M O R T #}
{##############################################################}
procedure Mort;
begin
dec(pepe.vides);
pepe.posX := 19;
pepe.posY := 23;
end;
{##############################################################}
{# M O R T M A L O #}
{##############################################################}
procedure MortMalo(num: byte);
begin
malo[num].posX := 39;
malo[num].posY := 1;
malo[num].color := 3;
malo[num].estat := caent;
malo[num].IAclock := 0;
mapa[malo[num].carrega.posX, malo[num].carrega.posY].tipo := diners;
malo[num].carrega.OK := false;
malo[num].carrega.posX := 0;
malo[num].carrega.posY := 0;
end;
{##############################################################}
{# F O R A D A R #}
{##############################################################}
procedure Foradar(posX, posY : word);
begin
{ mapa[posX, posY].tipo := buit;}
mapa[posX, posY].temps := bloc_out;
end;
{##############################################################}
{# M O U P E P E #}
{##############################################################}
procedure MouPepe;
var hi_ha_malo_baix : boolean;
begin
if TeclaPuls(KeyQ) then
begin
if mapa[pepe.posX, pepe.posY].tipo=escala then
begin
dec(pepe.posY);
end;
end
else
if TeclaPuls(KeyA) then
begin
if (mapa[pepe.posX, pepe.posY+1].tipo=escala) or (mapa[pepe.posX, pepe.posY+1].tipo=buit) then
inc(pepe.posY);
end;
if TeclaPuls(KeyO) then
begin
if (mapa[pepe.posX-1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
dec(pepe.posX);
end
else
if TeclaPuls(KeyP) then
begin
if (mapa[pepe.posX+1, pepe.posY].tipo<>pedra) and (pepe.estat<>caent) then
inc(pepe.posX);
end
else
if TeclaPuls(KeySPACE) then
begin
if (mapa[pepe.posX-1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX-1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX-1, pepe.posY+1);
end
else
if TeclaPuls(KeyM) then
begin
if (mapa[pepe.posX+1, pepe.posY+1].tipo=pedra)
and (mapa[pepe.posX+1, pepe.posY].tipo<>pedra)
and (pepe.estat=normal) then
Foradar(pepe.posX+1, pepe.posY+1);
end;
{ si no passa res... }
pepe.estat := normal;
{ final pantalla }
if pepe.posY = 1 then FinalPantalla;
{ emparedat }
if mapa[pepe.posX, pepe.posY].tipo = pedra then
Mort;
{ agarra diners }
if mapa[pepe.posX, pepe.posY].tipo = diners then
begin
mapa[pepe.posX, pepe.posY].tipo := buit;
inc(score);
dec(diners_pantalla);
end;
{ bordes X pantalla }
if pepe.posX<0 then pepe.posX:=0;
if pepe.posX>39 then pepe.posX:=39;
{ gravetat }
if ((mapa[pepe.posX, pepe.posY+1].tipo<>escala) and (mapa[pepe.posX, pepe.posY+1].tipo<>pedra))
and ((mapa[pepe.posX, pepe.posY].tipo=buit) or (mapa[pepe.posX, pepe.posY].tipo=diners)) then
begin
hi_ha_malo_baix := FALSE;
for i:=0 to num_malos-1 do
if (pepe.posX = malo[i].posX) and (pepe.posY+1 = malo[i].posY) then
hi_ha_malo_baix := TRUE;
if not(hi_ha_malo_baix) then
begin
inc(pepe.posY);
pepe.estat := caent;
end;
end;
{ bordes Y pantalla }
if pepe.posY<0 then pepe.posY:=0;
if pepe.posY>24 then pepe.posY:=24;
end;
{##############################################################}
{# S E L E C T E S T A T #}
{##############################################################}
function SelectEstat(num: byte):byte;
var nou_estat : byte;
Sestat:byte;
x:byte;
estat_pX,estat_pY:byte;
buscar:byte;
begin
nou_estat := 0;
Sestat:=0;
if mapa[malo[num].posX+1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+dreta;
if mapa[malo[num].posX-1, malo[num].posY].tipo <> pedra then
nou_estat := nou_estat+esquerra;
if mapa[malo[num].posX, malo[num].posY].tipo = escala then
nou_estat := nou_estat + pujar;
if mapa[malo[num].posX, malo[num].posY+1].tipo = escala then
nou_estat := nou_estat + baixar;
if nou_estat=0 then Sestat:=10; {no pot moure's}
if malo[num].posX>pepe.posX then estat_pX:=esquerra
else estat_pX:=dreta;
if malo[num].posY>pepe.posY then estat_pY:=pujar
else estat_pY:=baixar;
x:=random(4);
buscar:=random(100);
if (buscar<50) and ((nou_estat and estat_PX=estat_PX) or
(nou_estat and estat_PY=estat_PY)) then
begin
if (nou_estat and estat_PX=estat_PX) then Sestat:=estat_PX
else Sestat:=estat_PY;
end
else
repeat
case x of
0:if nou_estat and dreta =dreta then Sestat:=dreta;
1:if nou_estat and esquerra =esquerra then Sestat:=esquerra;
2:if nou_estat and pujar =pujar then Sestat:=pujar;
3:if nou_estat and baixar =baixar then Sestat:=baixar;
end;
inc(x);
x:=x and $03;
until Sestat<>0;
SelectEstat:=Sestat;
if (mapa[malo[num].posX, malo[num].posY+1].tipo <> pedra)
and (mapa[malo[num].posX, malo[num].posY+1].tipo <> escala) then
SelectEstat:=caent;
end;
{##############################################################}
{# A G A F A R E S C A L A #}
{##############################################################}
function AgafarEscala(num:byte):byte;
var x:byte;
ag:boolean;
estat:byte;
begin
estat:=malo[num].estat;
if (estat=dreta) or (estat=esquerra) then
begin
x:=random(100);
if x<80 then ag:=True else ag:=false;
if ag then
begin
if (mapa[malo[num].posX, malo[num].posY].tipo = escala) then
estat:=pujar
else
if (mapa[malo[num].posX, malo[num].posY+1].tipo = escala) then
estat:=baixar;
end;
end;
AgafarEscala:=estat;
end;
{##############################################################}
{# M O U M A L O S #}
{##############################################################}
procedure MouMalos;
begin
for i:=0 to num_malos-1 do
begin
if malo[i].IAclock = 0 then
malo[i].estat := SelectEstat(i);
malo[i].estat:=AgafarEscala(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo <> pedra) and
(mapa[malo[i].posX, malo[i].posY+1].tipo <> escala)) and
(mapa[malo[i].posX, malo[i].posY].tipo <> corda) then
malo[i].estat:=caent;
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) or
(mapa[malo[i].posX, malo[i].posY+1].tipo = escala)) and
(malo[i].estat=caent) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY].tipo = buit) and
(malo[i].estat=pujar)) then
malo[i].estat:=SelectEstat(i);
if ((mapa[malo[i].posX, malo[i].posY+1].tipo = pedra) and
(malo[i].estat=baixar)) then
malo[i].estat:=SelectEstat(i);
case malo[i].estat of
dreta : inc(malo[i].posX);
esquerra : dec(malo[i].posX);
pujar : dec(malo[i].posY);
baixar : inc(malo[i].posY);
caent : inc(malo[i].posY);
end;
{ bordes X }
if malo[i].posX<0 then
begin
malo[i].posX:=0;
malo[i].estat := dreta;
end;
if malo[i].posX>39 then
begin
malo[i].posX:=39;
malo[i].estat := esquerra;
end;
{ bordes Y }
if malo[i].posY<0 then
begin
malo[i].posY:=0;
end;
if malo[i].posY>24 then
begin
malo[i].posY:=24;
end;
{ agarrar diners }
if (mapa[malo[i].posX, malo[i].posY].tipo = diners)
and not(malo[i].carrega.OK) then
begin
mapa[malo[i].posX, malo[i].posY].tipo := buit;
malo[i].color := 11;
malo[i].carrega.OK := TRUE;
malo[i].carrega.posX := malo[i].posX;
malo[i].carrega.posY := malo[i].posY;
end;
{ emparedat }
if mapa[malo[i].posX, malo[i].posY].tipo = pedra then
MortMalo(i);
inc(malo[i].IAclock);
if malo[i].IAclock = temps_IA then malo[i].IAclock := 0;
end;
end;
{##############################################################}
{# C A R R E G A M A P A #}
{##############################################################}
procedure CarregaMapa;
var fich : file of byte;
i,j : word;
buffer : byte;
begin
Assign(fich,'total.map');
Reset(fich);
Seek(fich, (level * 1000)+offset_mapa);
for i:=0 to 39 do
for j:=0 to 24 do
begin
Read(fich, buffer);
mapa[i,j].tipo:=buffer;
for k:=0 to num_items-1 do
if llista_items[k] = mapa[i,j].tipo then
mapa[i,j].color := color_items[k];
end;
Close(fich);
end;
{##############################################################}
{# C H E C K M O R T P E R M A L O S #}
{##############################################################}
procedure CheckMortPerMalos;
begin
for i:=0 to num_malos-1 do
if (malo[i].posX = pepe.posX) and (malo[i].posY = pepe.posY) then
Mort;
end;
{##############################################################}
{# C H E C K M A P A C O M P L E T #}
{##############################################################}
procedure CheckMapaComplet;
begin
if diners_pantalla = 0 then
for j:=1 to 23 do
begin
if mapa[0,j].tipo <> pedra then
begin
mapa[0,j].tipo := escala;
mapa[0,j].color := color_escala;
end
else
break;
end;
end;
{##############################################################}
{# C H E C K M A P A #}
{##############################################################}
procedure CheckMapa;
begin
for i:=0 to 39 do
for j:=0 to 24 do
begin
case mapa[i,j].temps of
0 : begin
mapa[i,j].temps := -1;
mapa[i,j].tipo := pedra;
end;
1,bloc_out-1 : begin
mapa[i,j].tipo := bloc3;
dec(mapa[i,j].temps)
end;
2,bloc_out-2 : begin
mapa[i,j].tipo := bloc2;
dec(mapa[i,j].temps)
end;
3,bloc_out-3 : begin
mapa[i,j].tipo := bloc1;
dec(mapa[i,j].temps)
end;
4,bloc_out-4 : begin
mapa[i,j].tipo := buit;
dec(mapa[i,j].temps)
end;
-1 : ;
else dec(mapa[i,j].temps)
end;
end;
CheckMapaComplet;
end;
{##############################################################}
{# F A S E N O V A #}
{##############################################################}
procedure FaseNova;
begin
inc(level);
if level=(num_fases + 1) then
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# I N I C I A L I T Z A C I O #}
{##############################################################}
procedure Inicialitzacio;
begin
level := 1;
pepe.posX := 19;
pepe.posY := 23;
pepe.dibuix := 2;
pepe.color := 15;
pepe.vides := 0;
malo[0].posX := 9;
malo[0].posY := 2;
malo[0].dibuix := ord('X');
malo[0].color := 3;
malo[0].carrega.OK := FALSE;
malo[0].estat := esquerra;
malo[0].IAclock := 0;
malo[1].posX := 20;
malo[1].posY := 2;
malo[1].dibuix := ord('X');
malo[1].color := 3;
malo[1].carrega.OK := FALSE;
malo[1].estat := esquerra;
malo[1].IAclock := 0;
malo[2].posX := 39;
malo[2].posY := 2;
malo[2].dibuix := ord('X');
malo[2].color := 3;
malo[2].carrega.OK := FALSE;
malo[2].estat := esquerra;
malo[2].IAclock := 0;
CarregaMapa;
clock := 0;
diners_pantalla := 0;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mapa[i,j].temps := -1;
if mapa[i,j].tipo = diners then
inc(diners_pantalla);
end;
end;
{##############################################################}
{# T I T O L #}
{##############################################################}
procedure Titol;
begin
getpaleta(paleta);
blackout;
PutStringCENTERED(10, 15, 'JAILDESIGNER');
PutStringCENTERED(12, 15, 'presenta');
FadeUp(paleta, 1);
for i:=0 to 100 do espera_VGA;
Fadedown(0,0,0,0);
level := 0;
CarregaMapa;
for i:=0 to 39 do
for j:=0 to 24 do
begin
mem[pant1:(i shl 1)+(j*80)]:=mapa[i,j].tipo;
mem[pant1:(i shl 1)+1+(j*80)]:=mapa[i,j].color;
end;
move(mem[pant1:0], mem[$B800:0], 2000);
FadeUp(paleta, 0);
for i:=0 to 100 do espera_VGA;
for k:=0 to 2 do
begin
{ despla‡a cap amunt }
for i:=0 to 39 do
for j:=0 to 23 do
begin
mem[pant1:(i shl 1)+(j*80)] := mem[pant1:(i shl 1)+((j+1)*80)];
mem[pant1:(i shl 1)+1+(j*80)] := mem[pant1:(i shl 1)+1+((j+1)*80)];
end;
espera_VGA;espera_VGA;espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
end;
end;
{##############################################################}
{# M E N U #}
{##############################################################}
procedure Menu;
var num : integer;
begin
num := 1;
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'OPCIONS');
repeat
repeat until QteclaPuls;
if (TeclaPuls(KeyA)) then
num := 2;
if (TeclaPuls(KeyQ)) then
num := 1;
espera_VGA;
move(mem[pant1:0], mem[$B800:0], 2000);
if num = 1 then
begin
PutStringWINDOWED(18, 14, 'COMEN€AR JOC');
PutStringCENTERED(20, 15, 'EIXIR');
end
else
begin
PutStringCENTERED(18, 15, 'COMEN€AR JOC');
PutStringWINDOWED(20, 14, 'EIXIR');
end;
until TeclaPuls(KeyENTER);
if num = 2 then
{ menu d'opcions }
exit_game := TRUE;
;
end;
{##############################################################}
begin
instalarKB;
setmode(1);
HideCursor;
SetUpVirtual(ptrpant1, pant1);
randomize;
offset_mapa := OffsetMapa;
exit_game := FALSE;
repeat
Titol;
Menu;
Inicialitzacio;
CarregaRecords;
repeat
MouPepe;
CheckMortPerMalos;
if (Clock mod 4) = 0 then MouMalos;
CheckMortPerMalos;
PintaPantalla;
CheckMapa;
until TeclaPuls(KeyESC) or (Pepe.vides<0);
GameOver;
until exit_game;
TancarVirtual(ptrpant1);
setmode(3);
desinstalarKB;
end.