//============================================================================
// control/server/server.cs
//  Copyright (c) 2003, 2006 by Kenneth C.  Finney.
//============================================================================
function OnServerCreated()
//----------------------------------------------------------------------------
// Once the engine has fired up the server, this function is called
//----------------------------------------------------------------------------
{
 Exec("./misc/sndprofiles.cs"); 

   Exec("./misc/camera.cs");
   Exec("./misc/shapeBase.cs");
   Exec("./misc/item.cs");
   Exec("./misc/marker.cs");
   Exec("./misc/weather.cs");

   Exec("./players/player.cs");
   Exec("./players/beast.cs");
   Exec("./players/ai.cs");
   Exec("./weapons/weapon.cs");
   Exec("./weapons/crossbow.cs");
Exec("./weapons/tommygun.cs");///***KCF***24/09/2006 7:15PM
Exec("./vehicles/car.cs");///***KCF***24/09/2006 8:29PM
 Exec("./misc/particles.cs");///***KCF***24/09/2006 9:51PM
 exec("./misc/tracktriggers.cs");///***KCF***24/09/2006 11:53PM
}
function StartGame()
{
  if ($Game::Duration) // Start the game timer
    $Game::Schedule = Schedule($Game::Duration * 1000, 0, "onGameDurationEnd");
  $Game::Running = true;
 // schedule( 2000, 0, "CreateBots");
 PlaceCoins();
}
function PlaceCoins()
{
%W=GetWord(MissionArea.area,2);
%H=GetWord(MissionArea.area,3);
%west = GetWord(MissionArea.area,0);
%south = GetWord(MissionArea.area,1);
  new SimSet (CoinGroup);
  for (%i = 0; %i < 4; %i++)
  {
    %x = GetRandom(%W) + %west;
    %y = GetRandom(%H) + %south;
    %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ShapeBaseObjectType;
    %scanTarg = ContainerRayCast(%x SPC %y SPC "500", %x SPC %y SPC "-100", %searchMasks);
    if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
    {
      %newpos = GetWord(%scanTarg,1)  SPC GetWord(%scanTarg,2) SPC GetWord(%scanTarg,3) + 1;
    }
    %coin = new Item("Gold "@%i) {
      position = %newpos;
      rotation = "1 0 0 0";
      scale = "5 5 5";
      dataBlock = "Gold";
      collideable = "0";
      static = "0";
      rotate = "1";
    };
    MissionCleanup.add(%coin);
    CoinGroup.add(%coin);
  }
  // repeat above for silver coin
  for (%i = 0; %i < 8; %i++)
  {
    %x = GetRandom(%W) + %west;
    %y = GetRandom(%H) + %south;
    %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ShapeBaseObjectType;
    %scanTarg = ContainerRayCast(%x SPC %y SPC "500", %x SPC %y SPC "-100", %searchMasks);
    if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
    {
      %newpos = GetWord(%scanTarg,1)  SPC GetWord(%scanTarg,2) SPC GetWord(%scanTarg,3) + 1;
    }
    %coin = new Item("Silver "@%i) {
      position = %newpos;
      rotation = "1 0 0 0";
      scale = "5 5 5";
      dataBlock = "Silver";
      collideable = "0";
      static = "0";
      rotate = "1";
    };
    MissionCleanup.add(%coin);
    CoinGroup.add(%coin);
  }
  // repeat above for copper coin
  for (%i = 0; %i < 32; %i++)
  {
    %x = GetRandom(%W) + %west;
    %y = GetRandom(%H) + %south;
    %searchMasks = $TypeMasks::PlayerObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ShapeBaseObjectType;
    %scanTarg = ContainerRayCast(%x SPC %y SPC "500", %x SPC %y SPC "-100", %searchMasks);
    if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType))
    {
      %newpos = GetWord(%scanTarg,1)  SPC GetWord(%scanTarg,2) SPC GetWord(%scanTarg,3) + 1;
    }
    %coin = new Item("Copper "@%i) {
      position = %newpos;
      rotation = "1 0 0 0";
      scale = "5 5 5";
      dataBlock = "Copper";
      collideable = "0";
      static = "0";
      rotate = "1";
    };
    MissionCleanup.add(%coin);
    CoinGroup.add(%coin);
  }
}

function OnMissionLoaded()
{
   StartGame();
}
function OnMissionEnded()
{
   Cancel($Game::Schedule);
   $Game::Running = false;
}
function GameConnection::OnClientEnterGame(%this)
{
   // Create a new camera object.
   %this.camera = new Camera() {
      dataBlock = Observer;
   };
   MissionCleanup.Add( %this.camera );
   %this.camera.ScopeToClient(%this);
   %this.SpawnPlayer();
}
function GameConnection::SpawnPlayer(%this)
{

//   %this.CreatePlayer("0 0 201 1 0 0 0");
   %this.createPlayer(SelectSpawn());///***KCF***24/09/2006 10:42PM
}
function SelectSpawn()
{
   %groupName = "MissionGroup/PlayerSpawns";
   %group = nameToID(%groupName);

   if (%group != -1) {
      %count = %group.getCount();
      if (%count != 0) {
         %index = getRandom(%count-1);
         %spawn = %group.getObject(%index);
         return %spawn.getTransform();
      }
      else
         error("No spawn points found in " @ %groupName);
   }
   else
      error("Missing spawn points group " @ %groupName);

   return "0 0 201 1 0 0 0"; // if no spawn points then center of world
}


function GameConnection::CreatePlayer(%this, %spawnPoint)
{
   if (%this.player > 0)//The player should NOT already have an avatar object.
   {                     // If he does, that's a Bad Thing.
      Error( "Attempting to create an angus ghost!" );
   }
   // Create the player object
   %player = new Player() {
      dataBlock = MaleAvatar;   // defined in players/player.cs
      client = %this;           // the avatar will have a pointer to its
   };                           // owner's GameConnection object
   %player.SetTransform(%spawnPoint); // where to put it
   // Update the camera to start with the player
   %this.camera.SetTransform(%player.GetEyeTransform());
   %player.SetEnergyLevel(100);
   // Give the client control of the player
   %this.player = %player;
   %this.setControlObject(%player);
   
   %this.lapsCompleted = 0;
   %this.cpCompleted = 0;
   %this.ResetCPs();

   %this.position = 0;
   %this.money = 0;
   %this.deaths = 0;
   %this.kills = 0;
   %this.score = 0;

   
}
function GameConnection::OnDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc)
{
   // Switch the client over to the death cam and unhook the player object.
   if (IsObject(%this.camera) && IsObject(%this.player))
   {
      %this.camera.SetMode("Death",%this.player);
      %this.setControlObject(%this.camera);
   }
   %this.player = 0;
   if (%damageType $= "Suicide" || %sourceClient == %this)
   {
   }
   else
   {
     // good hit
   }
  %this.deaths++;
  %this.DoScore();   
  %sourceClient = %sourceObject ? %sourceObject.client : 0;
   if (%obj.getState() $= "Dead")
   {
      if (isObject(%sourceClient))
      {
         %sourceClient.incScore(1);
         if (isObject(%client))
            %client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
      }
   }


}
//============================================================================
// Server commands
//============================================================================
function ServerCmdToggleCamera(%client)
{
   %co = %client.getControlObject();
   if (%co == %client.player)
   {
      %co = %client.camera;
      %co.mode = toggleCameraFly;
   }
   else
   {
      %co = %client.player;
      %co.mode = observerFly;
   }
   %client.SetControlObject(%co);
}
function ServerCmdDropPlayerAtCamera(%client)
{
   if ($Server::DevMode || IsObject(EditorGui))
   {
      %client.player.SetTransform(%client.camera.GetTransform());
      %client.player.SetVelocity("0 0 0");
      %client.SetControlObject(%client.player);
   }
}
function ServerCmdDropCameraAtPlayer(%client)
{
   %client.camera.SetTransform(%client.player.GetEyeTransform());
   %client.camera.SetVelocity("0 0 0");
   %client.SetControlObject(%client.camera);
}
function ServerCmdUse(%client,%data)
{
   %client.GetControlObject().use(%data);
}
// stubs
function ClearCenterPrintAll()
{
}
function ClearBottomPrintAll()
{
}
function onNeedRelight()
{
}


function GameConnection::ResetCPs(%client)
{
    for (%i = 0; %i < $Game::NumberOfCheckpoints; %i++)
      %client.cpCompleted[%i]=false;
}
function GameConnection::CheckProgress(%client, %cpnumber)
{
    for (%i = 0; %i < %cpnumber; %i++)
    {
      if (%client.cpCompleted[%i]==false)
        return false;
    }
    %client.cpCompleted = %cpnumber;
    return true;
}
function GameConnection::UpdateLap(%client,%trigger,%obj)
{
  if (%trigger.cp==0)
  {
    if (%client.CheckProgress($Game::NumberOfCheckpoints))
    {
        %client.ResetCPs();
        %client.cpCompleted[0] = true;
        %client.lapsCompleted++;
        %client.DoScore();
        if(%client.lapsCompleted >= $Game::NumberOfLaps)
          EndGame();
    }
    else
    {
      %client.cpCompleted[0] = true;
      %client.DoScore();
    }
  }
  else if (%client.CheckProgress(%trigger.cp))
  {
    %client.cpCompleted[%trigger.cp] = true;
    %client.DoScore();
  }
}
function GameConnection::DoScore(%client)
{   
	%client.score = (%client.lapsCompleted * $Game::Laps_Multiplier) +
                  (%client.money * $Game::Money_Multiplier) +
                  (%client.deaths * $Game::Deaths_Multiplier) +
                  (%client.kills * $Game::Kills_Multiplier) ;

  %scoreString  =           %client.score         @
                  " Lap:" @ %client.lapsCompleted @
                  " CP:"  @ %client.cpCompleted+1 @
                  " $:"   @ %client.money         @
                  " D:"   @ %client.deaths        @
                  " K:"   @ %client.kills;
  commandToClient(%client, 'UpdateScore', %scoreString);
    if (%client.score >= $Game::MaxPoints)
    cycleGame();

}
function cycleGame()
{
   if (!$Game::Cycling) {
      $Game::Cycling = true;
      $Game::Schedule = schedule(0, 0, "onCycleExec");
   }
}
function onCycleExec()
{
   endGame();
   $Game::Schedule = schedule($Game::EndGamePause * 1000, 0, "onCyclePauseEnd");
}

function onCyclePauseEnd()
{
   $Game::Cycling = false;
   %search = $Server::MissionFileSpec;
   for (%file = findFirstFile(%search); %file !$= "";
         %file = findNextFile(%search)) {
      if (%file $= $Server::MissionFile) {
         %file = findNextFile(%search);
         if (%file $= "")
           %file = findFirstFile(%search);
         break;
      }
   }
   loadMission(%file);
}
