// hunters game mode

if (!$gameModeAdded["Hunters"])
{
$gameModeAdded["Hunters"] = true;
$gameModeName[$nGameMode] = "Hunters";
$gameModePrintName[$nGameMode] = "Hunters";
$gameModePrintInServerList[$nGameMode] = true;
$nGameMode ++;
}



////////////////////////////////////////////////////////////////////////////////
// initialisation stuff

// called when the server loads the map
function Hunters::ServerStarted(%this)
{
   if ($debugMissionLoad)
      echo("GMServerStarted Hunters");

   $GMMissionArea = MissionArea;

   $nexus = new Item()
   {
      dataBlock = NexusBall;
      particleMode = 2;
      gameModeItem = true;
      scale = "3 3 3";
   };

   MissionCleanup.add($nexus);

   setArtefactOccasionalMove($nexus);
   $nexus.setScopeAlways();

   $nRubies = 0;
   
   $RubySet = new SimSet()
   {
   };

   setNewNexusPos();

   //spawnRuby();

   $fightInfo.farAwayRadar = false;

   $radarItems = true;

   $gameModePrintText = "Playing Hunters: collect shields when they drop from the corpses of enemies, and take them to the Nexus to get points.  Take more shields at once for a bonus.";
   
   setTimedRoundsOn($Pref::Server::hunDefaultRoundTime, "None 2 5 10 20 30");
   
   setWeaponsListOn($Pref::Server::hunDefaultWeaponList, $Pref::Server::hunWeaponLists);
}


function setNewNexusPos()
{  
   %x = getRandom() * 2048 - 1045;
   %y = getRandom() * 2048 - 1024;

   %worldXY = %x SPC %y;

   %hhh = 10;

   %z = getTerrainOrWaterHeight(%worldXY) + %hhh;

   $nexus.setTransform(%worldXY SPC %z SPC "1 0 0 0");
}


function spawnRuby()
{
   %MAX_RUBIES = 5;

   if ($nRubies < %MAX_RUBIES)
   {
      %ruby = new Item()
      {
         dataBlock = Ruby;
         particleMode = 1;
         gameModeItem = true;
      };

      //$debugRuby = %ruby;  

      MissionCleanUp.add(%ruby);
      
      $RubySet.add(%ruby);

      %x = getRandom() * 2048 - 1024;
      %y = getRandom() * 2048 - 1024;   

      %nexusPos = $nexus.getTransform();

      %x += getWord(%nexusPos, 0);
      %y += getWord(%nexusPos, 1);

      %z = getTerrainOrWaterHeight(%x SPC %y) + 10;

      %ruby.setTransform(%x SPC %y SPC %z SPC "1 0 0 0");
   
      $nRubies ++;

      messageAll('NewRuby', 'A shield has been spawned');
   }

   $spawnRubySchedule = schedule(60000, 0, "spawnRuby");
}



function Hunters::playerHitItem(%this, %player, %item)
{
   if (%item == $nexus)
   {
      playerHitNexus(%player);
   }
   else if (%item.isRuby && %item.canPickupRuby)
   {
      $nRubies --;

      %item.canPickupRuby = false;
      %player.nRubies += 1;
      setRubies(%player.client, %player.nRubies);

      %item.setTransform("0 0 -200 1 0 0 0");
      schedule(1000, 0, "deleteItem", %item);

      messageAll('PickupRuby', %player.client.name SPC "has" SPC %player.nRubies SPC "rubies.", %player.client);
   }
}


function playerHitNexus(%player)
{
   %score = 0.5 * %player.nRubies * (%player.nRubies + 1);

   if (%score > 0)
   {
      increaseScore(%player.client, %score);

      messageAll('RubyCashed', %player.client.name SPC "cashed in" SPC %player.nRubies SPC "shields for" SPC %score SPC "points.", %player.client);
   }

   %player.nRubies = 0;

   setRubies(%player.client, %player.nRubies);
}

///////////////////////////////////////////////////////////////////////////////
// player/client management stuff

// new client entering the game
function Hunters::ClientEnterGame(%this, %client)
{

   if ($debugMissionLoad)
      echo("GMClientEnterGame Hunters");
}

// client fully loaded
function Hunters::ClientFullyLoaded(%this, %client)
{
   if ($debugMissionLoad)
      echo("GMClientFullyLoaded Hunters");


   commandToClient(%client, 'setVisible', "JoinFightButton", 1);
   commandToClient(%client, 'setVisible', "AddBotButton", 1);
   commandToClient(%client, 'setVisible', "DuelChallengeButton", 0);
   commandToClient(%client, 'setVisible', "DuelAcceptButton", 0);
   commandToClient(%client, 'setVisible', "ChallengeBotButton", 0);
}

// returns true if this client is allowed to join the match
function Hunters::CanJoinMatch(%this, %client)
{
  return (!%client.inFight && $nPlayers < $nSlots);
}

// called on a player joining the match.  Newclient indicates whether the client has been in the match before
function Hunters::JoinMatch(%this, %client, %character, %newClient, %team)
{
   %client.player.nRubies = 0;
   setRubies(%client, %client.player.nRubies);

   if (%client.player.isABot)
   {
      %client.player.setAiState("ChaseFacingOff");
   }
}

// called on a client dropping for any reason
function Hunters::ClientDropped(%this, %client, %reason)
{

}

// called on a client leaving the match
function Hunters::ClientLeavingMatch(%this, %client)
{
   commandToClient(%client, 'SetBottomPrintText', "Left click to continue.", -1);
}

// called on player death or client leaving the match
function Hunters::RemovePlayer(%this, %player)
{

}

// call the client and tell him what colours we want the IFFs to be
function Hunters::SendClientIFFInfo(%this, %client)
{
   commandToClient(%client, 'setIFFColours', "0 1 0", "1 0 0", "0 0 1", "0 1 1", false);
}

//////////////////////////////////////////////////////////////////
// action stuff

// called on a player-player collision
function Hunters::OnHit(%this, %hiter, %hitee, %myHitbox, %hisHitbox, %myForce, %hisForce, %myMult, %hisMult, %winner, %myV2, %hisV2)
{
   return standardHitDamage(%hiter, %hitee, %myHitbox, %hisHitbox, %myForce, %hisForce, %myMult, %hisMult, %winner, %myV2, %hisV2);
}





// called when a player is killed by an opponent
function Hunters::OnKilled(%this, %killee, %killer)
{
   %killer.setDamageLevel(%killer.getDamageLevel() - 25);

   schedule(1000, 0, "standardKillMessage", %killee, %killer, %reason);   
}

// called on a player's death
function Hunters::OnDeath(%this, %player)
{
   %killee = %player;

   %initVel = %killee.getVelocity();

   %killee.nRubies += 1; // we add one for his, erm, soul

   if (!$killingDueToRoundEnd)
   {
      for (%i = 0; %i < %killee.nRubies; %i ++)
      {
         //%angle = getRandom() * 2 * 3.1415;
         //%radius = 5;
      
        
         %x = getRandom() * 2 - 1;
         %y = getRandom() * 2 - 1;
         %z = (getRandom() * 2 - 1) * 0.1;

         %vec = VectorNormalize(%x SPC %y SPC %z);

         %trans = VectorAdd(%vec, getWords(%killee.getTransform(), 0, 2)) SPC "1 0 0 0";

         %item = new Item()
         {
            dataBlock = ShieldItem;
            particleMode = 3;
            gameModeItem = true;
            scale = "5 5 5";

            isPowerUp = false;

            isRuby = true;
            canPickupRuby = false;
         };

         schedule(1000, 0, "setCanPickup", %item);

         MissionCleanUp.add(%item);
         
         $RubySet.add(%item);

         %item.setTransform(%killee.getTransform());
         %item.setVelocity(getRandomVector(70, 30));

         $nRubies ++;
      }
   }
   
   %player.nRubies = 0;
   setRubies(%player.client, %player.nRubies);
}



function setCanPickup(%item)
{
   %item.canPickupRuby = true;
}


function Hunters::onTimedRoundEndRound(%this)
{
   //error("----------------------END ROUND------");
   removeAllRubies();

   for (%i = 0; %i < ClientGroup.getCount(); %i ++)
   {
      %c = ClientGroup.getObject(%i);

      %c.player.nRubies = 0;
      setRubies(%c, 0);
   }
}

function removeAllRubies()
{
   
   %n = $RubySet.getCount();

   error("removing rubies " @ %n);
   
   for (%i = 0; %i < %n; %i ++)
   {
      %ruby[%i] = $rubySet.getObject(%i);
   }
   
   for (%i = 0; %i < %n; %i ++)
   {
      error("removing ruby: " @ %ruby[%i]);
      %ruby[%i].delete();
   }
}


/////////////////////////////////////////////////////////////////////
// mission area stuff

// called when the player enters the MissionArea mission area struct
function Hunters::OnEnterMissionArea(%this, %player)
{
   
}

// called when the player leaves the MissionArea mission area struct
function Hunters::OnLeaveMissionArea(%this, %player)
{
  
}


////////////////////////////////////////////////////////////////////
// mission end cleanup


function Hunters::OnMissionEnded(%this)
{
   cancel($spawnRubySchedule);
   
   $RubySet.delete();

   finishWarpArtefact($nexus);
}

////////////////////////////////////////////////////////////////////
// ball stuff

// player collides with the ball
function Hunters::PlayerHitBall(%this, %player, %hitboxID, %ball)
{

}




