//  Natural Disaster Test Code


     //--------------------------------------
    //
   //  Natural disaster coding for CTP2
  //    by the Immortal Wombat
 //
//-----------------------------------------


  //----------
 // Variables
//------------

// Co-ordinates

int_t	maxX;
int_t	maxY;

int_t	vX;
int_t	vY;

// Game stuff, players and units

int_t	NumPlayers;        // How many players ?
int_t	human;		// The human player

location_t QuakeLoc;

city_t theNearestCity;

//find thePlayer's theNearestCity to theLocation, outside or equal to theDistance boundary
//     return the distance from theLocation to theNearestCity
//     return -1 if no such city exists

int_f FindTheNearestCity( int_t thePlayer, location_t theLocation, int_t theDistance){

int_t smlDist;
int_t tmpDist;
int_t i;

city_t tmpCity;

    smlDist=1000; //initialize to some absurdly large number
    
    if (IsPlayerAlive(thePlayer)) {
         if (PlayerCityCount(thePlayer)> 0) {
	      for(i = 0; i < PlayerCityCount(thePlayer); i = i + 1) {
	           if(GetCityByIndex(thePlayer, i, tmpCity)) {
		        tmpDist = Distance(theLocation, tmpCity.location);
		        if (theDistance <= tmpDist && tmpDist < smlDist) {
			     smlDist = tmpDist;
			     theNearestCity = tmpCity;			    
		        }
	           }
	      }
              if (smlDist<1000) {
	           return smlDist; 
              }
	      else{
	           return -1;// no such city exists
	      }
         }
    }
    else{
	 return -1; // no cities at all or not a valid player
    }  
}

  //---------------------------------------
 //  Unit Damage code by Radical_Manouver
//-----------------------------------------

void_f QuakeDamage (location_t tmpLoc, int_t tmpDamage) {

int_t i;
unit_t tmpUnit;

	for (i = 0; i < GetUnitsAtLocation(tmpLoc); i = i + 1) {  
		GetUnitFromCell(tmpLoc, i, tmpUnit);
		if (tmpUnit.hp > 8) {
			DamageUnit(tmpunit, tmpDamage);
		}
	}
}

void_f	QuakeHitMessageNear () {

int_t DistanceFromCity;

         DistanceFromCity=FindTheNearestCity(human,QuakeLoc, 0);
	 if (-1<DistanceFromCity && DistanceFromCity<=4){
	//      message(theNearestCity.owner, 'HitNearYou');
	      if(theNearestCity.owner != human){
	//	   message(human, 'HitNearOther');
	      }
	 }	
}

  
    /////////////////////////////////
   //
  //   Earthquakes
 //
///////////////////////////////////

// for test messages, should be local:
int_t DistanceFromCity;
int_t	tmpX;
int_t	tmpY;
int_t	tmpRichter;
  //--------------------
 // Earthquake function
//----------------------
city_t tmpCity;

void_f Quake_Event () {

int_t i;
int_t j;
int_t	citypop;
int_t	tmpPops;

int_t	tmptmpRichter;


location_t nLoc;
location_t mLoc;

location_t tmpLoc;
	
    tmpX = Random(maxX);
    tmpY = Random(maxY);
    MakeLocation(QuakeLoc, tmpX, tmpY);

//for test, set the quake location
//    GetCityByIndex(player[0],0,tmpCity);
//    GetNeighbor(tmpCity.location,0,tmpLoc);
//    QuakeLoc=tmpLoc;
//    tmpX=QuakeLoc.x;
//    tmpY=QuakeLoc.y;


    tmptmpRichter = random(100);
    if(tmptmpRichter >= 97){
	 tmpRichter = 8;
    }
    elseif(tmptmpRichter >= 92){
	 tmpRichter = 7;
    }
    elseif(tmptmpRichter >= 82){
	 tmpRichter = 6;
    }
    elseif(tmptmpRichter >= 72){
	 tmpRichter = 5;
    }
    elseif(tmptmpRichter >= 60){
	 tmpRichter = 4;	
    }
    elseif(tmptmpRichter >= 45){
	 tmpRichter = 3;
    }
    elseif(tmptmpRichter >= 30){
	 tmpRichter = 2;
    } 
    else{
	 tmpRichter = 1;
    }

    GetCityByLocation(QuakeLoc, tmpCity);
    if(CityIsValid(tmpCity)){// there's a city at the epicenter
	 citypop = tmpCity.population;
	 if(tmpRichter >= 7){
	      tmpPops = citypop/2;
	      for(i = 0; i < tmpPops; i = i + 1){
		   AddPops(tmpCity,-1);
	      }
	      if(GetUnitsAtLocation(QuakeLoc) > 0){
		   QuakeDamage(QuakeLoc, 8);
	      }
	 }
	 elseif(tmpRichter >= 5){
	      tmpPops = citypop/3;
	      for(i = 0; i < tmpPops; i = i + 1){		 
		   AddPops(tmpCity,-1);
	      }
	      if(GetUnitsAtLocation(QuakeLoc) > 0){
		   QuakeDamage(QuakeLoc, 5);
	      }
	 }
	 elseif(tmpRichter >= 2){
	      tmpPops = citypop/4;
	      for(i = 0; i < tmpPops; i = i + 1){		 
		   AddPops(tmpCity,-1);
	      }
	      if(GetUnitsAtLocation(QuakeLoc) > 0){
		   QuakeDamage(QuakeLoc, 3);
	      }
	 }
	 else{
	      if(GetUnitsAtLocation(QuakeLoc) > 0){
	           QuakeDamage(QuakeLoc, 1);
	      }
	 } 
//	 message(tmpCity.owner, 'HitYourCity');
	 if(tmpCity.owner != human){
//	      message(human, 'HitOtherCity');
	 }
    } 
    else {//when there's no city at QuakeLoc, just kill the tile improvements
          for(i=0; i<24; i=i+1){
      	      if (TileHasImprovement(QuakeLoc, i)) {
		   Event:CutImprovements(QuakeLoc);
	      }
	 }
    }
    // now do the effects of the quake: 24 tiles to consider
    if(tmpRichter >= 3){
         for(i = 0; i < 8; i = i + 1){
	      GetNeighbor(QuakeLoc, i, nLoc);
              for(j=0; j<24; j=j+1){ // Cycle through first 24 tile improvements !!!

	           if (i == 0) {
		        if (TileHasImprovement(nLoc, j)) {
		             Event:CutImprovements(nLoc);
			}
		        if( tmpRichter >=5){
			     GetNeighbor(nLoc, 0, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			
		   }
		   if(i == 1){
		        if( tmpRichter >=4){
                             if (TileHasImprovement(nLoc, j)) {
		                  Event:CutImprovements(nLoc);
			     }
			}
                        if( tmpRichter ==8){
		             GetNeighbor(nLoc, 1, mLoc);
                             if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=7){
			     GetNeighbor(nLoc, 0, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=6){
			     GetNeighbor(nLoc, 2, mLoc);
                             if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
		   }
		   if(i == 2){
		        if (TileHasImprovement(nLoc, j)) {
		             Event:CutImprovements(nLoc);
			}                        
                        if( tmpRichter >=5){
			     GetNeighbor(nLoc, 2, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}			
		   }		
		   if(i == 3){
		        if( tmpRichter >=4){
			     if (TileHasImprovement(nLoc, j)) {
		                  Event:CutImprovements(nLoc);
			     }
			}
			if( tmpRichter ==8){
			     GetNeighbor(nLoc, 3, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=6){
			     GetNeighbor(nLoc, 5, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
                        if( tmpRichter >=7){
			     GetNeighbor(nLoc, 4, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}			
		   }			
		   if(i == 4){
		        if( tmpRichter >=4){
			     if (TileHasImprovement(nLoc, j)) {
		                  Event:CutImprovements(nLoc);
			     }
                        }
                        if( tmpRichter ==8){
			     GetNeighbor(nLoc, 4, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=6){
			     GetNeighbor(nLoc, 2, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=7){
			     GetNeighbor(nLoc, 7, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
		   }
		   if(i == 5 ){
		        if (TileHasImprovement(nLoc, j)) {
		             Event:CutImprovements(nLoc);
			}
                        if( tmpRichter ==8){
			     GetNeighbor(nLoc, 5, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
		             }
			}
		   }
		   if(i == 6){
		        if( tmpRichter >=6){
                             if (TileHasImprovement(nLoc, j)) {
		                  Event:CutImprovements(nLoc);
			     }
			}
                        if( tmpRichter ==8){
		             GetNeighbor(nLoc, 6, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
                        if( tmpRichter >=6){
		             GetNeighbor(nLoc, 5, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
			if( tmpRichter >=7){
		             GetNeighbor(nLoc, 7, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}
		   }
		   if(i == 7){
		        if (TileHasImprovement(nLoc, j)) {
		             Event:CutImprovements(nLoc);
			}
                        if( tmpRichter >=6){
		             GetNeighbor(nLoc, 7, mLoc);
			     if (TileHasImprovement(mLoc, j)) {
			          Event:CutImprovements(mLoc);
			     }
			}		        
		   }
	      }
	 }
    }
    if (CellOwner(QuakeLoc)>-1) {
         DistanceFromCity=FindTheNearestCity(CellOwner(QuakeLoc), QuakeLoc, 0);
         message(1,'theQuakeEvent');
	 if (0<DistanceFromCity && DistanceFromCity<=4){
	      message(theNearestCity.owner, 'HitNearYou');
	      if(theNearestCity.owner != player[0].owner){
        	   message(player[0], 'HitNearOther');
	      }
	 }    
    }
}

messagebox 'HitNearYou' {
	Show();
	Title(ID_QUAKE);
	Text(ID_QUAKE_NEAR_YOU);
//"An Earthquake occurred near {theNearestCity.name}"
}

messagebox 'HitNearOther' {
	Show();
	Title(ID_QUAKE);
	Text(ID_QUAKE_NEAR_OTHER);
//"An Earthquake occurred near {theNearestCity.name}"
}

messagebox 'theQuakeEvent' {

    show();
    eyepoint(QuakeLoc);
    Text (ID_MtheQuakeEvent) ;
//    MtheQuakeEvent "A quake happened at x={tmpX}, y={tmpY},
// \n theNearestCity is {theNearestCity.name},
// \n Richter val= {tmpRichter} Distance={DistanceFromCity}"
    
}

  //---------------------------------------------------
 // Other files, included after variables and functions
//-----------------------------------------------------

//#include "ND_msg.slc"
//#include "volcano.slc"

  //----------
 // Begin Scen
//------------

HandleEvent(BeginTurn) 'EQStart' pre {

int_t i;

	maxX = GetMapWidth();
	maxY = GetMapHeight();
	NumPlayers = preference("NumPlayers");
	DisableTrigger('EQStart');

	for(i = 1; i < NumPlayers; i = i + 1){
		if(IsHumanPlayer(i)){
			human = i;
		}
	}
	
}

HandleEvent(BeginTurn)'ReportData' post {

    if (player[0]==1) {
          message(1, 'StartData');
    }  
}

messagebox 'StartData' {

    show();
    Text (ID_MStartData) ;
    //MStartData  "human={human}" 
}


   //=============================
  //    DISASTER
 //                HANDLER
//================================

   //-----------------------------
  // Disasters included are:
 //   Plague, Earthquake, Volcano, Tsunami, Drought
//--------------------------------

HandleEvent(BeginTurn) 'EQ_RunEachTurn' post {


int_t i;
int_t j;
int_t QuakeChance;

city_t tmpCity;

location_t nLoc;
location_t mLoc;

	if(g.year >= 3 && player[0] == 1){
		QuakeChance = random(19);
//		PlagueChance = random(14);
//		DroughtChance = random(19);
//		VolcanoChance = random(19);
//		if(DroughtChance >= 16){
//			Drought(player[0]);
//		}
//		if(PlagueChance >= 13){
//			plague(player[0]);
//		}
//		if(PlagueChance >= 11 && DroughtCount >= 14){
//			plague(player[0]);
//		}
		if(QuakeChance >= 1){
			Quake_Event();
		}
//		if(VolcanoChance >= 1){
//			VolcanoEvent();
//		}
//		for(i = 1; i < NumPlayers; i = i + 1){
//			EQ_Mess[i] = 0;
//		}
	}	
}


