//-----------------------------------------------------------------------------
// Torque Game Engine 
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

// Pause while looking over the end game screen (in secs)
$Game::EndGamePause = 10;


//-----------------------------------------------------------------------------
//  Functions that implement game-play
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

function onServerCreated()
{
   // Server::GameType is sent to the master server.
   // This variable should uniquely identify your game and/or mod.
   $Server::GameType = "Westward 2"; // AFX

   /// WESTWARD TODO: Something needs to be done with this
   // Server::MissionType sent to the master server.  Clients can
   // filter servers based on mission type.
   $Server::MissionType = "MageVSMage"; // AFX
   /// WESTWARD TODO

   // GameStartTime is the sim time the game started. Used to calculated
   // game elapsed time.
   $Game::StartTime = 0;
   
   // >> Westward 2 CODE BLOCK
   slgBuildMessageSystem();
   slgBuildObjectSystem();
   tsBuildServerTaskSystem();
   slgBuildServerCommandSystem();
   slgBuildObjectDatabase();
   slgBuildAISystem();
   slgAIRegisterCommands();
   slgHaltTimerUpdates();
   slgLoadObjectStrings();
   slgLoadBoosters();
   tsInitializeTaskSystem();
   initWaterTextures();
      
   // Must come after message and task systems have been created in order
   exec("./tasks/svr_taskconversions.cs");
   tsBuildInitialTasks();
   
   // Create Tech Tree manager
   new SLTechManager(GameTechManager);   
   GameTechManager.addTreeList("bldgtree");
   // << End Westward 2 CODE BLOCK
     
   // Keep track of when the game started
   $Game::StartTime = $Sim::Time;
}

function onServerDestroyed()
{
   // This function is called as part of a server shutdown.
   
   // >> Westward 2 CODE BLOCK
   if(isObject(GameTechManager)) {
      GameTechManager.delete();
   }
   if(isObject($DisasterManager)) {
      $DisasterManager.delete();
      $DisasterManager = 0;
   }
   
   DestroyResources();
   destroyTaskDlgData($TaskDlgData);
   uninitWaterTextures();
   slgShutdownTaskBuilder(); // Should ONLY happen on game exit
   slgDestroyClientCommandSystem();
   slgDestroyClientTaskSystem();
   slgDestroyAISystem();
   slgDestroyObjectDatabase();
   slgDestroyServerCommandSystem();
   tsDestroyServerTaskSystem();
   slgDestroyObjectSystem();
   slgDestroyMessageSystem();
   slgClearTimerFireMessages();
   // >> Westward 2 CODE BLOCK
}


//-----------------------------------------------------------------------------

function onMissionLoaded()
{
   // Called by loadMission() once the mission is finished loading.
   // Nothing special for now, just start up the game play.
   startGame();
}

function onMissionEnded()
{
   // Called by endMission(), right before the mission is destroyed

   // Normally the game should be ended first before the next
   // mission is loaded, this is here in case loadMission has been
   // called directly.  The mission will be ended if the server
   // is destroyed, so we only need to cleanup here.
   cancel($Game::Schedule);
   $Game::Running = false;
   $Game::Cycling = false;
}


//-----------------------------------------------------------------------------

function startGame()
{
   if ($Game::Running) {
      error("startGame: End the game first!");
      return;
   }

   // Inform the client we're starting up
   for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
      %cl = ClientGroup.getObject( %clientIndex );
      commandToClient(%cl, 'GameStart');

      // Other client specific setup..
      %cl.score = 0;
   }

   $Game::Running = true;
}

function endGame()
{
   if (!$Game::Running)  {
      error("endGame: No game running!");
      return;
   }

   // Stop any game timers
   cancel($Game::Schedule);

   // Inform the client the game is over
   for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
      %cl = ClientGroup.getObject( %clientIndex );
      commandToClient(%cl, 'GameEnd');
   }

   // Delete all the temporary mission objects
   resetMission();
   $Game::Running = false;
}

//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// GameConnection Methods
// These methods are extensions to the GameConnection class. Extending
// GameConnection make is easier to deal with some of this functionality,
// but these could also be implemented as stand-alone functions.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------


$serverCamera = 0;
function GameConnection::onClientEnterGame(%this)
{
   // Sync clock does nothing on client
   //commandToClient(%this, 'SyncClock', $Sim::Time - $Game::StartTime);
   
   // Create camera and components

   // iterate through all cameras in the game and load them (forces updates
   // to the cameras' global zoom positions and settings)
   if (LoadGodCameras(%this) == false)
   {
      %this.camera = new SLCamera(GameCamera)
      {
         dataBlock = GameCameraData;
      };
   }
   
   // Set portrait cameras
   HudCamera.camera     = PortraitCamera;
   TaskDlgCamera.camera = TaskPortraitCamera;
   
   if (%this.camera)
   {
      MissionCleanup.add( %this.camera );
      %this.camera.scopeToClient(%this);

      // Create a player object.
      %this.spawnPlayer(true);
   }
   
   // >> WESTWARD 2 CODE BLOCK
   // Resume timer updates
   slgResumeTimerUpdates();
   
   // Build tech for client
   GameTechManager.buildTech(%this);
   
   // Build inventory for client
   invInitClientInventory(%this);
   
   // << WESTWARD 2 CODE BLOCK
   
   $serverCamera = %this.getControlObject();
}

function GameConnection::onClientLeaveGame(%this)
{
   // >> WESTWARD 2 CODE BLOCK
   // Destroy inventory for client
   invDestroyInventory(%this);
   // << WESTWARD 2 CODE BLOCK
   
   if (isObject(%this.camera))
      %this.camera.delete();
   if (isObject(%this.player))
      %this.player.delete();
}


//-----------------------------------------------------------------------------

function GameConnection::onLeaveMissionArea(%this)
{
   // The control objects invoked this method when they
   // move out of the mission area.
}

function GameConnection::onEnterMissionArea(%this)
{
   // The control objects invoked this method when they
   // move back into the mission area.
}


//-----------------------------------------------------------------------------

function GameConnection::onDeath(%this, %sourceObject, %sourceClient, %damageType, %damLoc)
{
  // clear connections camera
  %this.clearCameraObject();
}


//-----------------------------------------------------------------------------

function GameConnection::spawnPlayer(%this, %first_spawn, %xfm)
{
   // clear out old linkages between player and client
   if (%this.player)
   {
     %this.player.client = 0;
     %this.player = 0;
   }

   // create player and drop him somewhere
   if (%xfm != 0)
     %spawnPoint = %xfm;
   else
    %spawnPoint = pickSpawnPoint();
   %this.createPlayer(%spawnPoint, %first_spawn);
}   


//-----------------------------------------------------------------------------
function GameConnection::createPlayer(%this, %spawnPoint, %first_spawn)
{
  // Give the client control of the camera
  %this.setControlObject(%this.camera);
  %this.camera.setTransform(%spawnPoint);
  
  // Get the position
  //%playerPos = %this.player.getPosition();
  
  // set up the portrait camera

  // We set the camera system to run in 3rd person mode around the %player
  %this.camera.setGodMode();
  %this.camera.setSpeed(525.0);
  %this.camera.setFov(10.0);
  %this.camera.setPosition(%spawnPoint, "0 0 1 1.57079632");

  %component = %this.camera.getCameraCmp();
  if (%component)
  {
      %component.rotationSpeed = 350;
      %component.snapSpeed = 7;
      %component.zoomSpeed = 500;

      // first value is the camera's distance from the target at this zoom position
      // the second value is the pitch of the camera at this zoom position
      // the third value is the yaw of the camera at this zoom position
      // the fourth value is the speed of the camera at this zoom position
      %component.addZoomData = "180 45 " @ $SLGodCamera::Yaw @ " 100";
      %component.addZoomData = "250 55 " @ $SLGodCamera::Yaw @ " 200";
      %component.addZoomData = "350 65 " @ $SLGodCamera::Yaw @ " 300";
      //%component.addZoomData = "1950 90 0 500"; // was used for map snapshot
      %component.setZoomPos(1); // called after zoom points are added
  }

  new afxSelectron(SelectedDecal)
  {
     dataBlock = AFX_OldDefault_SELE;
     addMainEffect = AFX_Old_Zode_EW;
  };
}

function BroadcastClearObjectSelection(%match_obj)
{
  %count = ClientGroup.getCount();
  for (%i = 0; %i < %count; %i++)
  {
    %cl = ClientGroup.getObject(%i);
    if( !%cl.isAIControlled() )
    {
      if (isObject(%match_obj))
      {
        %sel_obj = %cl.getSelectedObj();
        if (%sel_obj $= %match_obj)
          %cl.clearSelectedObj();
      }
      else
      {
        %cl.clearSelectedObj();
      }
    }
  }
}

//-----------------------------------------------------------------------------
// Support functions
//-----------------------------------------------------------------------------

function pickSpawnPoint(%groupName) 
{
   if (!isObject(%groupName))
      %groupName = "MissionGroup/PlayerDropPoints";
   %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);

   // Could be no spawn points, in which case we'll stick the
   // player at the center of the world.
   %center = getWorldCenter();
   return %center @ "100 1 0 0 0";
}

function serverCmdRebuildServerSystems(%client)
{
   slgDestroyMessageSystem();
   tsDestroyServerTaskSystem();
   slgDestroyServerCommandSystem();

   slgBuildMessageSystem();
   tsBuildServerTaskSystem();
   slgBuildServerCommandSystem();
   slgAIRegisterCommands();
   
   // Clear tech for client
   if(isObject(GameTechManager)) {
      GameTechManager.clearTech(%client);
   }
   
   // Clear upgrades and modifiers
   osResetModifierValues();
   csResetCmdUpgrades(%client);
   
   // Clear alert system
   alertSvrClearDatabase();
   
   // Clear all trains
   slgTrain_DestroyTrains();
   
   // Clear monitor booleans
   ResetMonitors();
}
