// Translocators script for EventScripts 1.5 by GODJonez
//  This server-side script addon enables players to be able to use 'translocator',
//  a personal device that can be thrown and to which the player can teleport to.
//  This makes it possible to use new tactics by quickly moving from one place to another in a map.
//  Players can also use the translocator as a spy device: it has built-in camera
//
// This script addon makes use of Auth service introduced in EventScripts 1.5
// In order for this script to work properly, you need to have a working Auth provider enabled
// More information about Auth can be found here: http://www.eventscripts.com/pages/Authorization_FAQ
//
// The two permissions this script uses are:
//  use_translocator
//   - allows the usage of the translocator
//   - defaults to #known (people with validated steam account)
//  admin_translocator
//   - allows enabling/disabling this addon and setting customized players by say commands
//   - defaults to #admin
//
// To use translocator, the clients need to bind three keys, the commands to be bound are:
//  trans_throw
//   - throws the translocator or retrieves it back if thrown
//  trans_use
//   - teleports to where the translocator is, if thrown
//  trans_cam
//   - makes the players view use the camera in the translocator
//   - second use of this command returns to normal view
//
// The admins can use say command !trans to control the script, possible usage:
//  !trans 1
//   - enables the script functionality
//  !trans 0
//   - disables the script functionality
//  !trans del <user>
//   - deletes somebody from special list
//   - <user> can be userid, steamid or partial user name
//  !trans set <user> <t2 color> <t3 color>
//   - sets someone special colors
//   - <user> can be userid, steamid or partial user name
//   - <t2 color> is the color of the translocator when this user is playing in team 2 (in CS: Terrorist)
//   - <t3 color> is the color of the translocator when this user is playing in team 3 (in CS: Counter-T)
//
// NOTE: Specialized player colors do not work on servers with sv_lan set to 1!
//
// To use this script, add line "es_load translocator" to autoexec.cfg, after auth provider
// If you want bots to be able to use translocators also, add "es_load translocator/bots" to autoexec.cfg too

block load
{
  // This block is executed automatically when the script is loaded in autoexec.cfg
  
  // This script uses the following keygroups:
  //  trans_runtime
  //   - temporary keygroup to have runtime information of players
  //  trans_special
  //   - on-disk keygroup to save information of special players
  es_xkeygroupcreate trans_runtime
  es_xkeygroupload trans_special |translocator
  
  // Register client commands
  clientcmd create console "trans_throw" translocator/trans_throw "use_translocator" #known
  clientcmd create console "trans_use" translocator/trans_use "use_translocator" #known
  clientcmd create console "trans_cam" translocator/trans_cam "use_translocator" #known
  clientcmd create say "!trhelp" translocator/trans_help "use_translocator" #known
  
  clientcmd create say "!trans" translocator/trans_admin "admin_translocator" #admin
  
  // Create and initialize runtime variables used by this script:
  es_xset translocators "1" "0 = Translocator script disabled, 1 = Translocator script enabled"
  es_xset _rt_trans_color "0" "Translocator color"
  es_xset _rt_trans_userid "0" "Player's user id"
  es_xset _rt_trans_userid2 "0" "Player's user id"
  es_xset _rt_trans_steamid "0" "Player's steam id"
  es_xset _rt_trans_team "0" "Player's team"
  es_xset _rt_trans_team2 "0" "Player's team"
  es_xset _rt_trans_name "0" "Player's name"
  es_xset _rt_trans_name2 "0" "Player's name"
  es_xset _rt_trans_temp "0" "Temporary variable to used for simple checks such as exists"
  es_xset _rt_trans_index "0" "Translocator entity index"
  es_xset _rt_trans_save "0" "Tracks changes to special keygroup"
  es_xset _rt_trans_com "0" "Command from client"
  
  es_xset _rt_trans_r "0" "Red color"
  es_xset _rt_trans_g "0" "Green color"
  es_xset _rt_trans_b "0" "Blue color"
  es_xset _rt_trans_model "0" "Translocator model index"
  es_xset _rt_trans_vec1 "0" "Player vector"
  es_xset _rt_trans_vec2 "0" "Locator vector"
  
  // Let the translocators be seen in server queries
  es_xmakepublic translocators
  
  // Load custom events
  es_xloadevents declare addons/eventscripts/translocator/es_translocator.res
  
  ifx true(eventscripts_currentmap) do
  {
    // Game is going already! We need to get the player info
    es_xdoblock translocator/import_players
    es_xprecachemodel _rt_trans_model "models/Effects/combineball.mdl"
    es_xloadevents addons/eventscripts/translocator/es_translocator.res
  }
  
  // Register special server-side command
  es_xexists _rt_trans_temp command translocator_checkfall
  ifx false(_rt_trans_temp) do
  {
    es_xregcmd translocator_checkfall translocator/checkfall "Check if player is falling outside world"
  }
}

block unload
{
  // This block is executed automatically when the script is unloaded with es_unload
  
  // Handle keygroups
  ifx true(_rt_trans_save) do
  {
    es_xkeygroupsave trans_special |translocator
  }
  es_xkeygroupdelete trans_special
  es_xkeygroupdelete trans_runtime
  
  // Handle client commands
  clientcmd delete console trans_throw
  clientcmd delete console trans_use
  clientcmd delete console trans_cam
  clientcmd delete say !trans
  
  // Show that the script is not enabled anymore
  es_xset translocators 0
}

block disable
{
  // This block is executed automatically when the script is disabled
  es_xset translocators 0
  
  // Check if there have been changes to special playerlist and save them
  ifx true(_rt_trans_save) do
  {
    es_xkeygroupsave trans_special |translocator
    es_xset _rt_trans_save 0
  }
}

block enable
{
  // This block is executed automatically when the script is enabled again
  es_xset translocators 1
}

event es_map_start
{
  es_xloadevents addons/eventscripts/translocator/es_translocator.res
  // Recache the model
  es_xprecachemodel _rt_trans_model "models/Effects/combineball.mdl"
}

event player_connect
{
  // We have a new player on the server
  es_keycreate trans_runtime event_var(userid)
}

event player_disconnect
{
  // We lost a player
  es_keydelete trans_runtime event_var(userid)
}

event player_activate
{
  // The player is ready to start playing
  
  // Does this player have special config?
  es_exists _rt_trans_temp key trans_special event_var(es_steamid)
  ifx true(_rt_trans_temp) do
  {
    es_keygetvalue _rt_trans_color trans_special event_var(es_steamid) "2"
    es_keysetvalue trans_runtime event_var(userid) "2" server_var(_rt_trans_color)
    es_keygetvalue _rt_trans_color trans_special event_var(es_steamid) "3"
    es_keysetvalue trans_runtime event_var(userid) "3" server_var(_rt_trans_color)
  }
  else do
  {
    // No special config, use default colors
    es_keysetvalue trans_runtime event_var(userid) "2" "-16776961"
    es_keysetvalue trans_runtime event_var(userid) "3" "-32768"
  }
  es_keysetvalue trans_runtime event_var(userid) "color" "-1"
  es_keysetvalue trans_runtime event_var(userid) "translocator" "0"
  es_keysetvalue trans_runtime event_var(userid) "camera" "0"
}

block import_players
{
  // Go through all current players and set their info
  es_xcreateplayerlist trans_players
  es_xforeachkey _rt_trans_userid in trans_players "es_xdoblock translocator/import_a_player"
  es_xkeygroupdelete trans_players
}

block import_a_player
{
  es_keycreate trans_runtime server_var(_rt_trans_userid)
  es_keygetvalue _rt_trans_steamid trans_players server_var(_rt_trans_userid) steamid
  es_exists _rt_trans_temp key trans_special server_var(_rt_trans_steamid)
  ifx true(_rt_trans_temp) do
  {
    es_keygetvalue _rt_trans_color trans_special server_var(_rt_trans_steamid) "2"
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "2" server_var(_rt_trans_color)
    es_keygetvalue _rt_trans_color trans_special server_var(_rt_trans_steamid) "3"
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "3" server_var(_rt_trans_color)
  }
  else do
  {
    // No special config, use default colors
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "2" "-16776961"
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "3" "-32768"
  }
  es_keygetvalue _rt_trans_team trans_players server_var(_rt_trans_userid) teamid
  if (server_var(_rt_trans_team) > 1) do
  {
    es_keygetvalue _rt_trans_color trans_runtime server_var(_rt_trans_userid) server_var(_rt_trans_team)
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "color" server_var(_rt_trans_color)
  }
  else do
  {  
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "color" "-1"
  }
  es_keysetvalue trans_runtime server_var(_rt_trans_userid) "translocator" "0"
  es_keysetvalue trans_runtime server_var(_rt_trans_userid) "camera" "0"
}

event player_team
{
  es_exists _rt_trans_temp key trans_runtime event_var(userid)
  ifx true(_rt_trans_temp) do
  {
    // A player changed team, update his translocator color
    es_keygetvalue _rt_trans_index trans_runtime event_var(userid) translocator
    if (event_var(team) > 1) do
    {
      es_keygetvalue _rt_trans_color trans_runtime event_var(userid) event_var(team)
      es_keysetvalue trans_runtime event_var(userid) "color" server_var(_rt_trans_color)
      ifx true(_rt_trans_index) do
      {
        es_setindexprop server_var(_rt_trans_index) CBaseEntity.m_clrRender server_var(_rt_trans_color)
      }
    }
    else do
    {  
      es_keysetvalue trans_runtime event_var(userid) "color" "-1"
      ifx true(_rt_trans_index) do
      {
        es_remove server_var(_rt_trans_index)
        es_keysetvalue trans_runtime event_var(userid) "translocator" "0"
      }
    }
  }
}

event round_end
{
  // Check if there have been changes to special playerlist and save them
  ifx true(_rt_trans_save) do
  {
    es_xkeygroupsave trans_special |translocator
    es_xset _rt_trans_save 0
  }
}

event player_death
{
  // Remove translocator
  es_keygetvalue _rt_trans_index trans_runtime event_var(userid) translocator
  ifx true(_rt_trans_index) do
  {
    // The translocator is already somewhere, will not be any longer
    es_remove server_var(_rt_trans_index)
    es_keysetvalue trans_runtime event_var(userid) translocator 0
  }
}

event round_start
{
  es_xforeachkey _rt_trans_userid in trans_runtime "es_xdoblock translocator/resetplayer"
  ifx true(translocators) do
  {
    es_xmsg #multi #green[translocators]#default Type#lightgreen !trhelp#default to chat for info!
  }
}

block resetplayer
{
  es_keysetvalue trans_runtime server_var(_rt_trans_userid) translocator 0
  es_keysetvalue trans_runtime server_var(_rt_trans_userid) camera 0
}

// CLIENT COMMAND BLOCKS

block trans_admin
{
  // Admin block
  es_xgetargv _rt_trans_com 1
  es_xgetcmduserid _rt_trans_userid
  
  if (server_var(_rt_trans_com) == "1") do
  {
    es_xenable translocator
  }
  else do
  {
    if (server_var(_rt_trans_com) == "0") do
    {
      es_xdisable translocator
    }
    else do
    {
      if (server_var(_rt_trans_com) == "del") do
      {
        es_xdoblock translocator/trans_admin_del
      }
      else do
      {
        if (server_var(_rt_trans_com) == "set") do
        {
          es_xdoblock translocator/trans_admin_set
        }
        else do
        {
          es_tell server_var(_rt_trans_userid) Subcommands: 0, 1, del, set
        }
      }
    }
  }
}

block trans_admin_del
{
  es_xgetargv _rt_trans_temp 2
  es_getuserid _rt_trans_userid server_var(_rt_trans_temp)
  ifx true(_rt_trans_userid) do
  {
    es_getplayersteamid _rt_trans_steamid server_var(_rt_trans_userid)
    es_exists _rt_trans_temp key trans_special server_var(_rt_trans_steamid)
    ifx true(_rt_trans_temp) do
    {
      es_keydelete trans_special server_var(_rt_trans_steamid)
      es_keysetvalue trans_runtime server_var(_rt_trans_userid) "2" "-16776961"
      es_keysetvalue trans_runtime server_var(_rt_trans_userid) "3" "-32768"
      es_keygetvalue _rt_trans_team trans_players server_var(_rt_trans_userid) team
      if (server_var(_rt_trans_team) > 1) do
      {
        es_keygetvalue _rt_trans_color trans_runtime server_var(_rt_trans_userid) server_var(_rt_trans_team)
        es_keysetvalue trans_runtime server_var(_rt_trans_userid) "color" server_var(_rt_trans_color)
      }
      es_getplayername _rt_trans_temp server_var(_rt_trans_userid)
      es_xformatv _rt_trans_temp "%1 no longer has special colors set" _rt_trans_temp
      es_xgetcmduserid _rt_trans_userid
      es_tell server_var(_rt_trans_userid) server_var(_rt_trans_temp)
    }
    else do
    {
      es_getplayername _rt_trans_temp server_var(_rt_trans_userid)
      es_xformatv _rt_trans_temp "%1 did not have special colors set" _rt_trans_temp
      es_xgetcmduserid _rt_trans_userid
      es_tell server_var(_rt_trans_userid) server_var(_rt_trans_temp)
    }
  }
  else do
  {
    es_xformatv _rt_trans_temp "No players matching %1%2%1 found" eventscripts_quote _rt_trans_temp
    es_xgetcmduserid _rt_trans_userid
    es_tell server_var(_rt_trans_userid) server_var(_rt_trans_temp)
  }
}

block trans_admin_set
{
  es_xgetargv _rt_trans_temp 2
  es_getuserid _rt_trans_userid server_var(_rt_trans_temp)
  ifx true(_rt_trans_userid) do
  {
    es_getplayersteamid _rt_trans_steamid server_var(_rt_trans_userid)
    es_exists _rt_trans_temp key trans_special server_var(_rt_trans_steamid)
    ifx false(_rt_trans_temp) do
    {
      es_keycreate trans_special server_var(_rt_trans_steamid)
    }
    es_xgetargv _rt_trans_r 3
    es_xgetargv _rt_trans_g 4
    es_xgetargv _rt_trans_b 5
    es_xmathparse _rt_trans_color "_rt_trans_r+256*_rt_trans_g+65536*_rt_trans_b-16777216"
    es_keysetvalue trans_special server_var(_rt_trans_steamid) "2" server_var(_rt_trans_color)
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "2" server_var(_rt_trans_color)

    es_xgetargv _rt_trans_r 6
    es_xgetargv _rt_trans_g 7
    es_xgetargv _rt_trans_b 8
    es_xmathparse _rt_trans_color "_rt_trans_r+256*_rt_trans_g+65536*_rt_trans_b-16777216"
    es_keysetvalue trans_special server_var(_rt_trans_steamid) "3" server_var(_rt_trans_color)
    es_keysetvalue trans_runtime server_var(_rt_trans_userid) "3" server_var(_rt_trans_color)
    es_keygetvalue _rt_trans_team trans_players server_var(_rt_trans_userid) team
    if (server_var(_rt_trans_team) > 1) do
    {
      es_keygetvalue _rt_trans_color trans_runtime server_var(_rt_trans_userid) server_var(_rt_trans_team)
      es_keysetvalue trans_runtime server_var(_rt_trans_userid) "color" server_var(_rt_trans_color)
    }
    es_getplayername _rt_trans_temp server_var(_rt_trans_userid)
    es_xformatv _rt_trans_temp "%1 now has special colors set" _rt_trans_temp
    es_xgetcmduserid _rt_trans_userid
    es_tell server_var(_rt_trans_userid) server_var(_rt_trans_temp)
  }
  else do
  {
    es_xformatv _rt_trans_temp "No players matching %1%2%1 found" eventscripts_quote _rt_trans_temp
    es_xgetcmduserid _rt_trans_userid
    es_tell server_var(_rt_trans_userid) server_var(_rt_trans_temp)
  }
}


block trans_throw
{
  ifx true(translocators) do
  {
    es_xgetcmduserid _rt_trans_userid
    es_getplayerteam _rt_trans_team server_var(_rt_trans_userid)
    if (server_var(_rt_trans_team) > 1) do
    {
      es playerget isdead _rt_trans_temp server_var(_rt_trans_userid)
      ifx false(_rt_trans_temp) do
      {
        es_keygetvalue _rt_trans_index trans_runtime server_var(_rt_trans_userid) translocator
        ifx true(_rt_trans_index) do
        {
          // The translocator is already somewhere, will not be any longer
          es_keygetvalue _rt_trans_temp trans_runtime server_var(_rt_trans_userid) camera
          ifx true(_rt_trans_temp) do
          {
            es_setview server_var(_rt_trans_userid) server_var(_rt_trans_temp)
            es_keysetvalue trans_runtime server_var(_rt_trans_userid) camera 0
          }
          es_remove server_var(_rt_trans_index)
          es_keysetvalue trans_runtime server_var(_rt_trans_userid) translocator 0
          es_xevent initialize translocator_retrieve
          es_event setint translocator_retrieve userid server_var(_rt_trans_userid)
          es_xevent fire translocator_retrieve
        }
        else do
        {
          // Throw the translocator!
          es_xevent initialize translocator_throw
          es_event setint translocator_throw userid server_var(_rt_trans_userid)
          // For the translocator we actually use prop_physics
          es_prop_physics_create server_var(_rt_trans_userid) "props_c17/metalPot001a.mdl"
          es_keysetvalue trans_runtime server_var(_rt_trans_userid) translocator server_var(eventscripts_lastgive)
          es_xcopy _rt_trans_index eventscripts_lastgive
          es_event setint translocator_throw trans_index server_var(_rt_trans_index)
          es_xformatv _rt_trans_temp "translocator_%1" _rt_trans_userid
          es est_setentname server_var(_rt_trans_index) server_var(_rt_trans_temp)
          es_event setint translocator_throw trans_name server_var(_rt_trans_temp)
          
          // Set model and correct color
          es_keygetvalue _rt_trans_color trans_runtime server_var(_rt_trans_userid) color
          es_setindexprop server_var(_rt_trans_index) "CBaseEntity.m_nModelIndex" server_var(_rt_trans_model)
          es_delayed 0 es_xsetindexprop server_var(_rt_trans_index) "CBaseEntity.m_clrRender" server_var(_rt_trans_color)
          
          // Set custom collision box model
          es_setindexprop server_var(_rt_trans_index) "CBaseEntity.m_Collision.m_vecMins" "-16.000000,-16.000000,-16.000000"
          es_setindexprop server_var(_rt_trans_index) "CBaseEntity.m_Collision.m_vecMaxs" "16.000000,16.000000,16.000000"
          es_setindexprop server_var(_rt_trans_index) "CBaseEntity.m_CollisionGroup" "0"
          
          // Set properties
          es_fire server_var(_rt_trans_userid) server_var(_rt_trans_temp) addoutput "spawnflags 9728"
          es_fire server_var(_rt_trans_userid) server_var(_rt_trans_temp) SetHealth "16777216"
          es_fire server_var(_rt_trans_userid) server_var(_rt_trans_temp) DisableShadow
          es_getplayerprop _rt_trans_vec1 server_var(_rt_trans_userid) "CBaseEntity.m_vecOrigin"
          es_getplayerprop _rt_trans_r server_var(_rt_trans_userid) "CBasePlayer.localdata.m_vecViewOffset[0]"
          es_getplayerprop _rt_trans_g server_var(_rt_trans_userid) "CBasePlayer.localdata.m_vecViewOffset[1]"
          es_getplayerprop _rt_trans_b server_var(_rt_trans_userid) "CBasePlayer.localdata.m_vecViewOffset[2]"
          es_createvectorstring _rt_trans_vec2 server_var(_rt_trans_r) server_var(_rt_trans_g) server_var(_rt_trans_b)
          es vecmath _rt_trans_vec1 server_var(_rt_trans_vec1) + server_var(_rt_trans_vec2)
          es_getindexprop _rt_trans_vec2 server_var(_rt_trans_index) "CBaseEntity.m_vecOrigin"
          es vecmath _rt_trans_vec2 server_var(_rt_trans_vec2) - server_var(_rt_trans_vec1)
          es vecmath _rt_trans_vec2 server_var(_rt_trans_vec2) setlength 32
          es vecmath _rt_trans_vec1 server_var(_rt_trans_vec1) + server_var(_rt_trans_vec2)
          es_delayed 0 es_xphysics active teleport server_var(_rt_trans_index) server_var(_rt_trans_vec1)
          es vecmath _rt_trans_vec2 server_var(_rt_trans_vec2) * 70
          es_delayed 0 es_xphysics active setvelocity server_var(_rt_trans_index) server_var(_rt_trans_vec2)
          es_xevent fire translocator_throw
        }
      }
    }
  }
}

block trans_use
{
  ifx true(translocators) do
  {
    es_xgetcmduserid _rt_trans_userid
    es_keygetvalue _rt_trans_index trans_runtime server_var(_rt_trans_userid) translocator
    ifx true(_rt_trans_index) do
    {
      // The translocator is somewhere, we can go there
      // Reset camera in case it was attached to the translocator
      es_keygetvalue _rt_trans_temp trans_runtime server_var(_rt_trans_userid) camera
      ifx true(_rt_trans_temp) do
      {
        es_setview server_var(_rt_trans_userid) server_var(_rt_trans_temp)
        es_keysetvalue trans_runtime server_var(_rt_trans_userid) camera 0
      }
      
      es_getindexprop _rt_trans_vec1 server_var(_rt_trans_index) "CBaseEntity.m_vecOrigin"
      es vecmath _rt_trans_vec1 server_var(_rt_trans_vec1) + "0,0,16"
      es_splitvectorstring _rt_trans_r _rt_trans_g _rt_trans_b server_var(_rt_trans_vec1)
      es_getplayerprop _rt_trans_vec2 server_var(_rt_trans_userid) "CBaseEntity.m_vecOrigin"
      // First remove the translocator
      es_remove server_var(_rt_trans_index)
      es_keysetvalue trans_runtime server_var(_rt_trans_userid) translocator 0
      // For possible telefragging, check if there are any people in area
      es_xset _rt_trans_userid2 0
      es est_nearcoord _rt_trans_userid2 #l 56 server_var(_rt_trans_r) server_var(_rt_trans_g) server_var(_rt_trans_b) "if (server_var(_rt_trans_userid2) != server_var(_rt_trans_userid)) then es_xgetplayerteam _rt_trans_team2 server_var(_rt_trans_userid2)"
      if (server_var(_rt_trans_userid2) == server_var(_rt_trans_userid)) then es_xset _rt_trans_userid2 0
      ifx true(_rt_trans_userid2) do
      {
        // Someone's there!
        ifx false(mp_friendlyfire) do
        {
          // Need to check for teams
          es_getplayerteam _rt_trans_team server_var(_rt_trans_userid)
          if (server_var(_rt_trans_team2) == server_var(_rt_trans_team)) then es_xset _rt_trans_userid2 0
        }
        ifx true(_rt_trans_userid2) do
        {
          // TELEFRAG!!
          es damage server_var(_rt_trans_userid2) 10000 32 server_var(_rt_trans_userid)
          es_xevent initialize translocator_telefrag
          es_event setint translocator_telefrag userid server_var(_rt_trans_userid2)
          es_event setint translocator_telefrag attacker server_var(_rt_trans_userid)
          es_xevent fire translocator_telefrag
        }
      }
      else do
      {
        es_xset _rt_trans_userid2 1
      }
      // Move it!
      ifx true(_rt_trans_userid2) do
      {
        es_xevent initialize translocator_teleport
        es_event setint translocator_teleport userid server_var(_rt_trans_userid)
        es_event setstring translocator_teleport trans_to server_var(_rt_trans_vec1)
        es_event setstring translocator_teleport trans_from server_var(_rt_trans_vec2)
        es est_teleport server_var(_rt_trans_userid) server_var(_rt_trans_r) server_var(_rt_trans_g) server_var(_rt_trans_b)
        es_delayed 1 translocator_checkfall server_var(_rt_trans_userid) server_var(_rt_trans_vec1) server_var(_rt_trans_vec2)
        es_effect energysplash server_var(_rt_trans_vec2) server_var(_rt_trans_vec1) 0
        es_effect energysplash server_var(_rt_trans_vec1) server_var(_rt_trans_vec2) 1
        es_xevent fire translocator_teleport
      }
    }
  }
}

block checkfall
{
  es_xgetargv _rt_trans_userid 1
  es_getplayerprop _rt_trans_vec1 server_var(_rt_trans_userid) "CBasePlayer.localdata.m_vecVelocity[2]"
  es_xmath _rt_trans_vec1 * -1
  es_getplayerprop _rt_trans_vec2 server_var(_rt_trans_userid) "CBasePlayer.m_flMaxspeed"
  if (server_var(_rt_trans_vec1) >= server_var(_rt_trans_vec2)) do
  {
    // Player is falling fast! let him go back
    es_setplayerprop server_var(_rt_trans_userid) "CBasePlayer.localdata.m_vecVelocity[2]" server_var(_rt_trans_vec1)
    es_xgetargv _rt_trans_vec1 3
    es_splitvectorstring _rt_trans_r _rt_trans_g _rt_trans_b server_var(_rt_trans_vec1)
    es_xmath _rt_trans_b + 50
    es est_teleport server_var(_rt_trans_userid) server_var(_rt_trans_r) server_var(_rt_trans_g) server_var(_rt_trans_b)
  }
  else do
  {
    es_getplayerprop _rt_trans_vec1 server_var(_rt_trans_userid) "CBaseEntity.m_vecOrigin"
    es_xgetargv _rt_trans_vec2 2
    if (server_var(_rt_trans_vec1) == server_var(_rt_trans_vec2)) do
    {
      // Player is stuck (or camping...)
      es_xgetargv _rt_trans_vec1 3
      es_splitvectorstring _rt_trans_r _rt_trans_g _rt_trans_b server_var(_rt_trans_vec1)
      es est_teleport server_var(_rt_trans_userid) server_var(_rt_trans_r) server_var(_rt_trans_g) server_var(_rt_trans_b)
    }
  }
}

block trans_cam
{
  ifx true(translocators) do
  {
    es_xgetcmduserid _rt_trans_userid
    es_keygetvalue _rt_trans_index trans_runtime server_var(_rt_trans_userid) translocator
    ifx true(_rt_trans_index) do
    {
      // The translocator is somewhere, we can use it
      es_xevent initialize translocator_camera
      es_event setint translocator_camera userid server_var(_rt_trans_userid)
      es_event setint translocator_camera trans_index server_var(_rt_trans_index)
      es_keygetvalue _rt_trans_temp trans_runtime server_var(_rt_trans_userid) camera
      ifx true(_rt_trans_temp) do
      {
        es_setview server_var(_rt_trans_userid) server_var(_rt_trans_temp)
        es_keysetvalue trans_runtime server_var(_rt_trans_userid) camera 0
        es_xevent setint translocator_camera trans_active 0
      }
      else do
      {
        // Attach view to translocator
        es_createplayerlist trans_players server_var(_rt_trans_userid)
        es_keygetvalue _rt_trans_temp trans_players server_var(_rt_trans_userid) index
        es_xkeygroupdelete trans_players
        es_keysetvalue trans_runtime server_var(_rt_trans_userid) camera server_var(_rt_trans_temp)
        es_setview server_var(_rt_trans_userid) server_var(_rt_trans_index)
        es_xevent setint translocator_camera trans_active 1
      }
      es_xevent fire translocator_camera
    }
  }
}

block trans_help
{
  es_xgetcmduserid _rt_trans_userid
  es_tell server_var(_rt_trans_userid) #green This server is using a translocator mod
  es_tell server_var(_rt_trans_userid) #multi #default Bind commands#lightgreen trans_throw#default,#lightgreen trans_use#default and#lightgreen trans_cam#default to use translocators!
  es_tell server_var(_rt_trans_userid) #multi #default Go to console and type for example#green bind MOUSE4 trans_use#default to bind mouse button 4 for that command.
}
