Program Iluvia;
Global
// Global vars block
grila;
nivel=1;
gotas;
bosque;fin;
elementos;musica;pant;
puntos;temperatura;fuente;fuentechica;
Local
estado=0; //todos los procesos tendrán su estado particular frio, caliente, agua y vapor
transicion=0; //es el tiempo de paso de un estado al otro
encendido=0; //para bloquear si se esta usando o no

Begin

set_mode(1280, 720, 32);
//      mode_change(mode_fullscreen);
set_fps(35,0);
load_fpg("graficos.fpg");
put_screen(0,2);
musica=song_load("musica.mp3",1);
fuente=load_fnt("fuente.fnt");
fuentechica=load_fnt("fuentechica.fnt");

song_play(musica);

repeat
transicion++;
put_screen(0,38);
frame;
until(transicion>300)


write(fuente,135,85,1,&Nivel);
write(fuente,135,175,1,&puntos);
write(fuentechica,120,220,1,"Max:");
write(fuentechica,140,220,0,&pant);

write(fuentechica,30,10,0,"Juego e Idea: Emmanuel Cesar Rubio");
write(fuentechica,30,30,0,"Música de fondo: Compositor Armónico en Fuga");


menu();

 Frame;

End

process menu();
private
int i;archivo;hex;int dato;
begin

archivo=fopen("svg.dat","r");
fread(offset dato,1,archivo);
fclose(archivo);
pant=dato;
if (puntos > dato)
archivo=fopen("svg.dat","w");
fwrite(offset puntos,sizeof(puntos),archivo);
fclose(archivo);
pant=puntos;
puntos=0;
end

let_me_alone();
put_screen(0,2);
fin=1;
Grilla();
for (bosque=0;bosque<100;bosque++)
  semilla();
end
for (i=0;i<5;i++)
  nube(rand(200,1000),rand(500,560));
  fabrica(rand(300,800),700);
end
        Dot(260,543,1);
        Dot(344,459,3);
        Dot(428,375,1); 
        Dot(512,291,2);  
        Dot(596,291,1);      
        Dot(680,375,3);
        Dot(764,459,2);
        Dot(512,543,3);
        
 while (!Mouse.left)

     frame;
     
 end
let_me_alone();
puntos=0;
nivel=1;
temperatura=0;
fin=0;
Grilla();
level();
termometro(1);
termometro(2);
for (bosque=0;bosque<100;bosque++)
  semilla();
end

end


process fire(x,y)
begin
size=-20;
graph=44;
loop
 if (collision(type eliminarpixel))
  size--;
  temperatura--;
 end
  if (collision(type tornado))
  size-=2;
  temperatura--;
 end
frame;
end
end

process semilla()
private
controlx;controly;fuego;i;
begin

  x=rand(250,1200);
  y=rand(697,710);
  graph=43;
  size=5;
transicion=0;

loop
   if (temperatura>1000)
     if (fuego==0)
      fuego=fire(x,y);    
     else
      if(fuego.size<120);
       fuego.size++;
      else
        temperatura+=2;
        size-=20;
        fuego.size=80;
      end
     end
   end
   if (temperatura<750)
     if (fuego<>0)
       if (fuego.size>20)
        fuego.size--;
       else
        signal(fuego,s_kill);
        fuego=0;
       end
     end
   end
      if (size<5)
        size=5;
       end
   if (temperatura<-700 & size>50)         
    temperatura-=10;
    size-=15;
   end
   
  if (collision(type eliminarpixel))
   if(size<300)
    size++;puntos++;
   end
  end
  
  if (size>80)
   transicion++;
  end
  
  if(transicion>600)
   i=rand(1,100);
   if (i>80)
    controlx= graphic_info(0, graph, g_width);
    controly= graphic_info(0, graph, g_height);
     if (temperatura>1500)
       elemento(rand(x-controlx/2,x+controlx/2),0,1,0);
       temperatura+=10;
     end
     if (temperatura>400)
       dot(rand(x-controlx/2,x+controlx/2),rand(y-controly/2,y+controly/2),4);
     end

     if (temperatura<300)
       elemento(rand(x-controlx/2,x+controlx/2),rand(y-controly/2,y+controly/2),2,0);
       temperatura-=10;
     end
   end
   transicion=0;
  end
  
  frame;
  
end
end

process level()
private
xd;
yd;teto[5];
sube=0;

begin
loop
if (key(_esc))
 delete_text(teto[1]);
 delete_text(teto[2]);
 delete_text(teto[3]);
 delete_text(teto[4]);
 delete_text(teto[5]);
 menu();
end
 
  if (sube==0)
    switch (nivel)
      case 1;
        Gotas=1;
        Dot(678,375,1);
        Nube(678,0);
        sube=1;
      end
      case 2;
        Gotas=1;
        Dot(594,291,1);
        Dot(510,291,2);
        Dot(550,110,4);
        Elemento(510,110,1,0);
        sube=1;
      end
      case 3;
        Gotas=1;
        Dot(762,375,1);
        Dot(678,291,2);
        Elemento(552,0,1,0);
        sube=1;
      end
      case 4;
        Gotas=1;
        Dot(678,375,3);
        Dot(764,375,3);
        Dot(848,375,3);
        Dot(764,291,1);
        Dot(764,720,4);        
        Elemento(552,0,2,0);
        sube=1;
      end
      case 5;
        Gotas=2;
        Dot(342,459,1);
        Dot(932,459,3);
        Dot(678,459,1);        
        Elemento(552,0,2,0);
        Elemento(426,0,2,0);
        sube=1;
      end
      case 6;
        Gotas=3;
        Dot(510,207,1);
        Dot(678,207,3);
        Dot(342,207,1); 
        Dot(848,207,1);       
        Elemento(932,0,2,0);
        Elemento(260,0,2,0);
        sube=1;
      end
      case 7;
        Gotas=4;
        Dot(510,543,1);
        Dot(678,459,3);
        Dot(342,375,1); 
        Dot(1016,207,1);  
        Dot(284,207,1);      
        Elemento(594,0,2,0);
        Elemento(426,0,2,0);
        sube=1;
      end
      case 8;
        Gotas=3;
        Dot(260,543,1);
        Dot(344,459,3);
        Dot(428,375,1); 
        Dot(512,375,2);  
        Dot(596,459,1);      
        Dot(680,543,3);
        Elemento(594,0,2,0);
        Elemento(426,0,2,0);
        sube=1;
      end
      case 9;
        Gotas=3;
        Dot(260,543,1);
        Dot(344,459,3);
        Dot(428,375,1); 
        Dot(512,291,2);  
        Dot(596,291,1);      
        Dot(680,375,3);
        Dot(764,459,2);
        Dot(512,543,3);
        Elemento(400,0,1,0);
        Elemento(300,0,1,0);        
        Elemento(544,0,2,0);
        Elemento(500,0,2,0);
        sube=1;
      end
      case 10;
        Gotas=3;

        Dot(428,375,1); 
        Dot(512,375,2);  
        Dot(596,459,3);      
        Dot(680,543,1);
        Dot(764,459,3);      
        Dot(848,543,3);
        Dot(932,543,1);
        Elemento(932,0,1,0);
        Elemento(1016,0,2,0);
        Elemento(260,0,1,0);
        Elemento(344,0,2,0);

        sube=1;
      end      
    end
  end
  if (gotas<=0 & nivel<10)
    sube=0;nivel++;
  end
  if (nivel==10)
    transicion++;   
     if(transicion>=1300)    
       fin=1;
       temperatura=0;

       teto[1]=write(fuentechica,650,320,1,"Espero que hayas disfrutado de este juego que simula");
       teto[2]=write(fuentechica,650,360,1,"el equilibrio y caos de algo tan simple como la lluvia...");
       teto[3]=write(fuentechica,650,400,1,"Comparte tu Score y vuelve a intentar mantener tu bosque,");
       teto[4]=write(fuentechica,650,440,1,"con más velocidad, experiencia y conociendo las transformaciones.");
       teto[5]=write(fuentechica,650,480,1,"ESC para salir");   
       repeat
           frame;
       until(key(_esc))
              delete_text(teto[1]);
              delete_text(teto[2]);
              delete_text(teto[3]);
              delete_text(teto[4]);
              delete_text(teto[5]);
       menu();
     end
     
  end
  
frame;  
end
end

Process Grilla()
private
    estad;
    xd;
    yd;

begin

z=-1000;
grila=id;
loop

    x=mouse.x;
    y=mouse.y;
     switch (estado)
       case 1;
        graph=8;
       end
       
       case 2;
        graph=9;
       end
       
       case 3;
        graph=10;
       end
       
       default:
        graph=7;
       end
       
     end

  if (mouse.right & estado>0)
  graph=7;
       switch (estado)
       case 1,2;
        elemento(x,y,estado,0);
       end
        case 3;
          xd=collision(type nube);
          if (xd)
            xd.encendido=0;
          end
        end 
       end       
  estado=0;
  end
          xd=collision(type nube);
          if (xd) if(xd.encendido==1 & estado<>3)
            xd.encendido=0;
          end end
       
  
  frame;
end

end

Process Dot(x,y,estado)
Private
    choqueelemento;
    choquenube;
    choque;
    distancia;
    angulo;
    gota;
begin
          size=0;
          graph=estado+10;
          gota=200+(nivel*10);
    loop
    if (size<100)
     size+=5;
    end  
    
      if (grila.estado>0)
       if (collision(type grilla))
        if(mouse.left)
          if (encendido==0)
            encendido=1;
            if (grila.estado<3)
              elemento(x,y,grila.estado,1);
            else
              if (estado==1)
                choque=collision(type nube);
                if (choque)
                  grila.estado=0;             
                  gotas--;
                  choque.encendido=0;
                  ataque(x,y,graph,choque,0); 
                  break;
                end
              end        
            end
            grila.estado=0;
          end
        end
       end
      end
      
      If (encendido)   
      choqueelemento=collision(type elemento);
      If (choqueelemento)
       choqueelemento.x=x;
       choqueelemento.y=y;
       choqueelemento.angle+=1000-transicion;
         if (choqueelemento.angle > 350000)
           choqueelemento.angle=0;
         end
         if (transicion < 150)
           transicion++;      
         else
         
//---------------------------------------------
//cambio de estado        
          switch (estado)
            case 1; //Normal
              estado=choqueelemento.estado+1;
              choqueelemento.estado=3;
              elementos--;
              gotas--;
            end
        
            case 2; //Caliente
              if (choqueelemento.estado==1)
                estado=4;
                choqueelemento.estado=3;
              else
              if (choqueelemento.estado==2)
                
                estado=1;
                choqueelemento.estado=3;
                elementos--;
              end
              end
            end
    
            case 3; //congelado
              if (choqueelemento.estado==1)
              
                estado=1;
                choqueelemento.estado=3;
                elementos--;              
              end
              if (choqueelemento.estado==2)               
                estado=2;
                choqueelemento.estado=2;
                preelemento(x,y+18,estado);
              end
            end                
            
            case 4; //gas
              if (choqueelemento.estado==1)
                choqueelemento.estado=3;
                elementos--;
                Nube(x,y);
                break; 
              end
              if (choqueelemento.estado==2)
                
                estado=1;
                choqueelemento.estado=1;  
              end
            end                   
          end
          choqueelemento.encendido=0;   
          graph=estado+10;
//-------------------------------------------------
        transicion=0;
        gota=200+(nivel*10);
        encendido=0;
      end//transicion    
    end//if choque      
  end//encendido
  

//------------------------------------------------
        gota--;
       choque=collision(type dot);
       if (choque)
         if (choque.estado<4 & estado<4)
            break;
         else        
         if (estado==4 & !encendido)
           if (choque.estado==4 & !choque.encendido)   
                  signal(choque,s_kill);
                  Nube(x,y);
                  break;
           end
         end
         end
       end
          switch (estado)
        
            case 1; //Normal
        
            end
        
            case 2; //Caliente
              
               if (gota<=0)
                gota=200+(nivel*12);
                temperatura+=5;
                preelemento(x+rand(-25,25),y+20,estado);
              end
              choque=collision(type nube);
              if (choque)
                gota-=20;
              end           
            end
    
            case 3; //congelado
              if (gota<=0)
                gota=200+(nivel*12);
                temperatura-=5;
                preelemento(x+rand(-25,25),y+20,estado);
              end
              choque=collision(type nube);
              if (choque)
                gota-=20;
              end
            end                
            
            case 4; //gas
              if (y>80)
              y--;
              end
              if (y<100)
              y+=2;
              end
              choque=fget_dist(x,y,grila.x,grila.y);
              if (choque<75 & choque>20)
                if (grila.estado==1)
                 angle=get_angle(grila);
                 advance(2);
                else
                  if (grila.estado==2)
                   angle=-get_angle(grila);
                   advance(2);
                  end
                end
              end      
            end                   
          end
      


        
    frame;
    end //endloop  
end

Process Elemento(x,y,estado,encendido)

private
  choque;i=0;a;
begin
  elementos++;
  loop
  graph=estado+20;
  if(fin==1)break;end
  if(collision(type tornado))
     break;
  end
  if (!encendido)
    switch (estado)
    case 1;
     if (temperatura<1300)
      temperatura++;
     end
    end
    case 2;
     if (temperatura>-500)
      temperatura--;
     end
    end
    end
  end 
  
   if (!encendido & graph<>23)
     if (collision(type grilla) & mouse.left);
       if (grila.estado==0)
          grila.estado=estado;
          break;
       end
       
       if (grila.estado==1 & estado==2)
          grila.estado=0;
          a=1;
          for (transicion=0;transicion<2;transicion++)
          for (i=0;i<20;i++)
            if (a==0)
            a=1;
            tornado(x+rand(-20,20)+i,y+rand(0,10)+35,a);
            else
            a=0;
            tornado(x+rand(-20,20)+i,y-rand(0,10)-35,a);
            end
            frame;
          end
          end
          break;
       end           
      
       if (grila.estado==2 & estado==1)
          grila.estado=0;
          a=2;
          for (transicion=0;transicion<2;transicion++)
          for (i=0;i<20;i++)
            if (a==3)
            a=2;
            tornado(x+rand(0,10)+35,y+rand(-20,20)+i,a);
            else
            a=3;
            tornado(x-rand(0,10)-35,y+rand(-20,20)+i,a);
            end
            frame;
          end
          end
          break;
       end 
          
     end//grila
     
     if (encendido==0)
      choque=collision(type dot);
      if (choque)
         if (choque.encendido==0)
            choque.encendido=1;
            encendido=1;
           for (i=0;i<20;i++)
            y+=2;
            frame;
           end  
            x=choque.x;
            y=choque.y;
         end
      end
     end
   end
     
   if (encendido==0 or graph==23)
     if (y<600)
       y+=(graph-18);
     else
       choque=collision(type elemento);
       if (y<700 & !choque)
         y+=(graph-18);
       else      
        if (graph==23)
           if (y<700)
            y+=(graph-18);
           else
            if (size>5)
                size--;
            end
            if (size<=5)
                transicion++;
                if(transicion>150)
                  fabrica(x,Y);
                  break;
                end 
            end           
          end                      
  
        else //no es plomo

       choque=collision(type elemento);
       transicion++;
       if (choque)
       if(choque.estado==1 & estado==2)
           tornado(x+rand(-20,20)+35,y+rand(-20,20)-35,rand(0,3));
           if(transicion==50)
             break;
           end
       else
           if(choque.estado==2 & estado==1)
             tornado(x+rand(-20,20)+35,y+rand(-20,20)-35,rand(0,3));
        if (estado==1)
         if(transicion==70)
           break;
         end
        else
          if(transicion==300)
           break;
          end
        end
           end
       end
       
       else //llego al fondo
        if (estado==1)
         if(transicion==70)
           break;
         end
        else
          if(transicion==300)
           break;
          end
        end
        
       end //choque           
      end //plomo
   end //choque
   end//580
  end//encendido

  
    
    frame;
  end
end

process preelemento(x,y,estado)
private
i;choque;choquehermano;
begin
graph=estado+20-1;
size=20;
loop
 
  if (y<720)
   y+=8-(estado*2);
   angle+=20000;
  else
   break;
  end
  if (collision(type tornado))
    break;
  end
  choque=collision(type nube);
  if (choque)
    for (i=0;i<80;i++)
     choque=collision(type nube);
     if (choque)
     y=choque.y;
     x=choque.x;
     else
     if (y<730)
     y--;
     end
     end
     size++;
     choquehermano=collision(type preelemento);
      if (choquehermano)
        signal(choquehermano,s_kill);
        size++;
        i++;
      end 
     frame;
    end
    elemento(x,y,estado-1,0);
    break;
  end 
  
  frame;
end
end

process fabrica(x,y)
private
controlx;controly;
begin
  transicion=0;
  graph=30;
  size_y=3;
  loop
    if(size_y<100)
    size_y++;
    end
    if(collision(type tornado))
     break;
    end
    if (nivel<6)
    transicion+=nivel;
    else
    transicion+=6;
    end  
    if(transicion>350 & !fin)
      transicion=0;
      nubenegra(x-15,y-110);  
    end
  frame;
  end
end

process nubenegra(x,y)
private
movimiento;
direccion;
begin
size=10;
graph=24;
estado=rand(50,130);
movimiento=rand(30,100);
direccion=rand(1,2);
  
 loop
    if(fin==1)break;end
    if(collision(type tornado))
      break;
    end
    if (movimiento>0)
      x+=direccion;
    else
     direccion=direccion*-1;
     movimiento=40;
    end
    if (x>1100)
    direccion=-1;
    movimiento=40;
    end
    if (x<200)
    direccion=1;
    movimiento=40;
    end
  if (size<estado)
    size+=4;
  end
    
  if (y>80)
    y-=rand(-2,4);
  end
    angle+=15000;
    transicion+=rand(-1,7);
  if (angle>340000) angle=0;end
  
  if (transicion>=1600)
    estado=elemento(x,y,1,0);
    break;    
  end
  frame;
 end 
end

Process Nube(x,y)
private
  movimiento;
  direccion;
begin
  graph=1;
  size=10;
  movimiento=40;
  direccion=1;

loop
  if (size<100)
  size+=3;
  end
  if(collision(type tornado))
   if(!collision(type ataque))
    break; 
   end
  end
   
  if (encendido==0)
    if (y<540)
      y+=3;
    end
    if (y>500)
      y-=3;
    end
    if (movimiento>0)
      x+=direccion;
    else
     direccion=direccion*-1;
     movimiento=40;
    end
    if (x>1100)
    direccion=-1;
    movimiento=40;
    end
    if (x<200)
    direccion=1;
    movimiento=40;
    end
  
  else
    x=grila.x;
    y=grila.y;
  end

 
  if (collision(type grilla) & encendido==0)
    if (grila.estado==0)
      if (!collision(type ataque))
        if (mouse.left)
          grila.estado=3;
          encendido=1;
        end
      end
    end
  end
  
    if (collision(type grilla) & encendido==1)
      if (grila.estado==0)
        if (collision(type ataque))
          encendido=0;
        end
      end
    end
  
  frame;
  
end
end

process termometro(estado)
private
calculo;
begin
  graph=estado+35;
  y=685;
  x=135;
  loop   
    if(estado==1)
       if(temperatura<2000)
         calculo=((temperatura*100)/2000);
       else
         temperatura=2000;
       end
    else
       if (temperatura>-1600)
         calculo=((temperatura*-1)*100)/1600;
       else
         temperatura=-1600;
       end
    end
    if (temperatura>=1900)
    transicion++;  
     if (transicion>=100)
       exit("Game Over por calor muy alto",0);
     end
     end
       
    if (temperatura<=-1500)
    transicion++;  
     if (transicion>=100)
       exit("Game Over por mucho frio",0);
     end
     end
if (calculo<2)
calculo=2;
end    
    size_y=calculo;
    frame;
  end
end
  

process tornado(x,y,estado)
private
choque;
begin
 graph=35;
 size=30;
 loop
  temperatura--;
  transicion+=rand(30,100);
  angle+=1500+transicion;
  
  switch (estado)
   Case 1;
    y+=transicion/100;
   end
   case 0;
    y-=transicion/100;
   end
   case 2;
   x+=transicion/100;
      choque=collision(type nube);
      if (choque)
        choque.x+=3;
      end
   end
   case 3;
   x-=transicion/100;
      choque=collision(type nube);
      if (choque)
        if (encendido==1)
        choque.encendido=0;
        grila.encendido=0;
        end
      end
   end
   end
   
  if (y>710 or y<100)
    break;
  end
  if (x>1270 or x<260)
    break;
  end
  

  if (collision (type grilla))
   grila.estado=0;
  end  

  frame;
 end
end


process ataque(x,y,idEnemigo,idperseguir,estado)//gotera
private
	contador, contador2;
	anchoGraficoEnemigo, altoGraficoEnemigo;
	color;
	
begin

	graph = map_clone(0, idEnemigo); //se clona el grafico del enemigo para no alterar el cargado en memoria
	anchoGraficoEnemigo = graphic_info(0, graph, g_width);
	altoGraficoEnemigo = graphic_info(0, graph, g_height);
	
	repeat

		for(contador = 0; contador < altoGraficoEnemigo; contador++)
  	if(idperseguir<>0)
  			x=idperseguir.x;
	    	y=idperseguir.y;
	  end
			//=====================
			//	lee hacia derecha
			//=====================
			
			for(contador2 = 0; contador2 < anchoGraficoEnemigo; contador2++)
					x=idperseguir.x;
      		y=idperseguir.y;
				if((color = map_get_pixel(0, graph, contador2, contador)) != rgb(0, 0, 0))
					eliminarPixel(x+contador2-anchograficoenemigo/2, y+contador, color,estado);
					map_put_pixel(0, graph, contador2, contador, rgb(0, 0, 0)); //se elimina el pixel leido por uno transparente
					frame(20);
					
				end
				
			end
			
			++contador; //se baja una fila
			
			//=====================
			//	lee hacia izquierda
			//=====================
			
			for(;contador2 > 0; contador2--)
  	if(idperseguir<>0)
  			x=idperseguir.x;
	    	y=idperseguir.y;
	  end
    
    	if((color = map_get_pixel(0, graph, contador2, contador)) != rgb(0, 0, 0))
					eliminarPixel(x+contador2-anchograficoenemigo/2 , y+contador, color,estado);
		 			map_put_pixel(0, graph, contador2, contador, rgb(0, 0, 0));
		  		frame(20);
			end
				
			end
			
			//=====================
			
		end
		
		frame;
		
	until(contador == altoGraficoEnemigo)
	idperseguir.encendido=0;
end

//**********************************

	//========================================
	//	adopta el color del pixel leido y actua dependiendo del modo
  //========================================

process eliminarPixel(x, y, color,estado)

private
	float coordY, coordX, aumY, aumY2, aumX;
		contador, contador2;
	anchoGrafico, altoGrafico;


begin
  z=100;
	graph = map_new(2, 6, color);
	coordY = y;
	coordx = x;
	
	switch (estado)
	
		case 1:
			aumY = rand(0.04f, 0.08f);
			aumY2 = rand(0.01f, 0.04f);
			
			repeat
				
				aumY += aumY2;
				coordY -= aumY;

				y = coordY;
		
				frame;		
			until(y < 520)			
		end
		
		case 2:
			aumY = rand(0.04f, 0.08f);
			aumY2 = rand(0.01f, 0.04f);
			
			repeat
		
				aumY += aumY2;
				coordY -= aumY;

				y = coordY;						

				frame;
				
			until(y < 520)
			
		end
		
		case 0:
			
			aumY = rand(-1.0f, -1.0f);
			aumY2 = rand(0.1f, 0.9f);
			aumX = rand(-2.0f, 2.0f);
			
			repeat
				
				coordX += aumX;
				aumY += aumY2;
				coordY += aumY;
				x = coordX;
				y = coordY;		
					frame;		
			until(y > 720 or collision(type semilla))
				
	end	
	end	
	map_unload(graph);

end


