Advertisement
Guest User

Untitled

a guest
Jul 21st, 2013
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 58.56 KB | None | 0 0
  1. #define VERSION "1.2.7"
  2.  
  3. public Plugin:myinfo = {
  4.     name = "JS_LJstats",
  5.     author = "justshoot, zipcore",
  6.     description = "Jump stats",
  7.     version = VERSION,
  8.     url = "jsbhop@gmail.com, zipcore#googlemail.com"
  9. };
  10.  
  11. #include <sdkhooks>
  12. #include <sdktools>
  13. #include <js_ljstats>
  14. #include <jsfunction>
  15. #include <smlib>
  16. #include <smlib/arrays>
  17.  
  18. #include <timer>
  19. #include <timer-logging>
  20. #include <timer-config_loader.sp>
  21.  
  22. #define LJDELAY 1.0
  23. #define ELSEDELAY 0.1
  24.  
  25. enum JumpType (+=1)
  26. {
  27.     JumpType_None = 0,
  28.     JumpType_LongJump,
  29.     JumpType_DropJump,
  30.     JumpType_UpJump,
  31.     JumpType_Ladder,
  32.     JumpType_Wj,
  33.     JumpType_WjDrop,
  34.     JumpType_WjUp,
  35.     JumpType_BhopJump,
  36.     JumpType_BhopUpJump,
  37.     JumpType_BlockLongJump,
  38.     JumpType_BlockBhopJump
  39. }
  40. enum ReadyType
  41. {
  42.     ReadyType_None,
  43.     ReadyType_LongJump,
  44.     ReadyType_BhopJump,
  45.     ReadyType_BhopUpJump,
  46.     ReadyType_Wj,
  47.     ReadyType_BlockLongJump,
  48.     ReadyType_BlockBhopJump
  49. }
  50.  
  51. new String:JumpName[JumpType][128] =
  52. {
  53.     "None",
  54.     "LongJump",
  55.     "DropJump",
  56.     "UpJump",
  57.     "LadderStrafe",
  58.     "WeirdJump",
  59.     "WeirdJump-Drop",
  60.     "WeirdJump+Up",
  61.     "BhopJump",
  62.     "BhopUpJump",
  63.     "BlockLongJump",
  64.     "BlockBhopJump"
  65. };
  66.  
  67. /**********************
  68. *   Player Variable   *
  69. **********************/
  70. new JumpType:PlayerJumpType[MAXPLAYERS + 1];
  71. new ReadyType:PlayerReadyType[MAXPLAYERS + 1];
  72. new bool:g_bLJmode[MAXPLAYERS + 1];
  73. new bool:g_bValidJump[MAXPLAYERS + 1];
  74. new Float:g_fJumpedPos[MAXPLAYERS + 1][3];
  75. new Float:g_fOnGroundPos[MAXPLAYERS + 1][3];
  76. new Float:PreStrafe[MAXPLAYERS + 1];
  77. new Float:OnGroundTime[MAXPLAYERS + 1];
  78. new bool:NoDucking[MAXPLAYERS + 1];
  79.  
  80. new g_Strafe[MAXPLAYERS + 1];
  81. new Float:LJ_SyncRate[MAXPLAYERS + 1];
  82. new Float:LJ_MaxSpeed[MAXPLAYERS + 1];
  83. #define MAXSTR 20
  84. new Float:LJ_SyncRateStrafe[MAXPLAYERS + 1][MAXSTR];
  85. new LJ_GoodSync[MAXPLAYERS + 1][MAXSTR];
  86. new LJ_BadSync[MAXPLAYERS + 1][MAXSTR];
  87. new Float:LJ_Gains[MAXPLAYERS + 1][MAXSTR];
  88. new Float:LJ_Lost[MAXPLAYERS + 1][MAXSTR];
  89. new LJ_Frame[MAXPLAYERS + 1][MAXSTR];
  90. new LJ_TotalFrame[MAXPLAYERS + 1];
  91. new Float:LJ_MaxSpeedStrafe[MAXPLAYERS + 1][MAXSTR];
  92.  
  93. new bool:g_bLJpopup[MAXPLAYERS + 1];
  94.  
  95. /**************************
  96. *       Block Jump        *
  97. **************************/
  98.  
  99. new Handle:h_LJBlockMenu = INVALID_HANDLE;      
  100. new bool:g_bLJBlock[MAXPLAYERS + 1];
  101. new Float:g_fBlockHeight[MAXPLAYERS + 1];
  102. new Float:g_EdgeVector[MAXPLAYERS + 1][3];
  103. new Float:g_EdgePoint[MAXPLAYERS + 1][3];
  104. new Float:g_EdgeDist[MAXPLAYERS + 1];
  105. new Float:g_OriginBlock[MAXPLAYERS + 1][2][3];
  106. new Float:g_DestBlock[MAXPLAYERS + 1][2][3];
  107. new g_BlockDist[MAXPLAYERS + 1];
  108.  
  109. /*********************
  110. *   Jump Stat Sound  *
  111. *********************/
  112.  
  113. new bool:g_bLJplaysnd[MAXPLAYERS + 1];
  114. new String:LJ_SOUND[5][256] =
  115. {
  116.     {"misc/impressive.wav"},
  117.     {"misc/perfect.wav"},
  118.     {"misc/mod_wickedsick.wav"},
  119.     {"misc/mod_godlike.wav"},
  120.     {"misc/holyshit.wav"}
  121. };
  122.  
  123. /*********************
  124. *   Create Natives   *
  125. *********************/
  126.  
  127. new Handle:g_LJMode_Forward = INVALID_HANDLE;
  128.  
  129. /********************
  130. *      ConVar       *
  131. ********************/
  132.  
  133. new Handle:g_hCvar_Show_Message = INVALID_HANDLE;
  134. new g_ShowMsg;
  135.  
  136. new Handle:g_hCvar_Invalid_Jump = INVALID_HANDLE;
  137. new Float:g_InvalidUnit;
  138.  
  139. new Handle:g_hCvar_Stop_LJ = INVALID_HANDLE;
  140. new Float:g_Stop_LJ;
  141.  
  142. new Handle:g_hCvar_Stop_BJ = INVALID_HANDLE;
  143. new Float:g_Stop_BJ;
  144.  
  145. new Handle:g_hCvar_Stop_BUJ = INVALID_HANDLE;
  146. new Float:g_Stop_BUJ;
  147.  
  148. new Handle:g_hCvar_Stop_Block_LJ = INVALID_HANDLE;
  149. new Float:g_Stop_Block_LJ;
  150.  
  151. new Handle:g_hCvar_Print_LJ = INVALID_HANDLE;
  152. new Float:g_Print_LJ;
  153.  
  154. new Handle:g_hCvar_Print_WJ = INVALID_HANDLE;
  155. new Float:g_Print_WJ;
  156.  
  157. new Handle:g_hCvar_Print_BJ = INVALID_HANDLE;
  158. new Float:g_Print_BJ;
  159.  
  160. new Handle:g_hCvar_Print_Block_LJ = INVALID_HANDLE;
  161. new Float:g_Print_Block_LJ;
  162.  
  163. new Handle:g_hCvar_Print_Block_BJ = INVALID_HANDLE;
  164. new Float:g_Print_Block_BJ;
  165.  
  166. new Handle:g_hCvar_DB_Record = INVALID_HANDLE;
  167. new Float:g_DB_Record;
  168.  
  169. new Handle:g_hCvar_Sound[5];
  170. new Float:g_Sound[5];
  171.  
  172. new bool:g_bLateLoaded;
  173.  
  174. /********************
  175. *     Measuring     *
  176. ********************/
  177. new g_Beam[2];
  178. new Float:AimPoint_1[MAXPLAYERS + 1][3];
  179. new Float:AimPoint_2[MAXPLAYERS + 1][3];
  180. new bool:AimDrawing[MAXPLAYERS + 1];
  181. new AimStatus[MAXPLAYERS + 1];
  182. new Handle:AimHandle[MAXPLAYERS + 1];
  183.  
  184. /*****************
  185. *  Top LJ Sqlite *
  186. ******************/
  187. new Handle:maindb = INVALID_HANDLE;
  188. new Handle:g_hCvar_DB = INVALID_HANDLE;
  189. new Handle:h_TopMenu = INVALID_HANDLE;
  190.  
  191. public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
  192. {
  193.     RegPluginLibrary("js_ljstats");
  194.     CreateNative("IsClientInLJMode", Native_IsClientInLJMode);
  195.     CreateNative("SetLJMode", Native_SetLJMode);
  196.     CreateNative("SetInValidJump", Native_SetInValidJump);
  197.     g_LJMode_Forward = CreateGlobalForward("OnClientLJModeChanged", ET_Hook, Param_Cell, Param_Cell);
  198.     g_bLateLoaded = late;
  199.     return APLRes_Success;
  200. }
  201. public Native_IsClientInLJMode(Handle:plugin, numParams)
  202. {
  203.     new client = GetNativeCell(1);
  204.     return g_bLJmode[client];
  205. }
  206. public Native_SetLJMode(Handle:plugin, numParams)
  207. {
  208.     new client = GetNativeCell(1);
  209.     new bool:on = GetNativeCell(2);
  210.    
  211.     if(on && !g_Physics[Timer_GetMode(client)][ModeLJStats])
  212.     {
  213.         //Don't allow wrong modes
  214.     }
  215.     else g_bLJmode[client] = on;
  216. }
  217. public Native_SetInValidJump(Handle:plugin, numParams)
  218. {
  219.     new client = GetNativeCell(1);
  220.     g_bValidJump[client] = false;
  221. }
  222. public OnPluginStart()
  223. {
  224.     CreateConVar("ljstats_version",VERSION,"Long Jump Stats - justshoot", FCVAR_PLUGIN|FCVAR_NOTIFY);
  225.     RegAdminCmd("sm_ljadm", Command_ljadm, ADMFLAG_ROOT, "Delete Record");
  226.     RegConsoleCmd("sm_lj", Command_ljmode, "Record Jump Stats");
  227.     RegConsoleCmd("sm_ljblock", Command_ljblock, "Register Destination");
  228.     RegConsoleCmd("sm_ljsound", Command_ljsound, "ljstats quake sound");
  229.     RegConsoleCmd("sm_ljpopup", Command_ljpopup, "Show/hide stats popup.");
  230.     RegConsoleCmd("sm_gap", Command_measure, "Measure units between 2 points");
  231.     RegConsoleCmd("sm_ljtop", Command_ljtop, "show ljstats top ranks");
  232.     HookEvent("player_jump", event_jump); //When players jumped
  233.     HookEvent("player_team", event_team);
  234.     HookEvent("round_start", event_roundstart);
  235.     g_hCvar_Show_Message = CreateConVar("ljstats_show_msg", "0", "0:All, 1:only for lj", FCVAR_PLUGIN);
  236.     g_hCvar_DB = CreateConVar("ljstats_db_name", "ljstats", "Database name, sqlite", FCVAR_PLUGIN);
  237.     g_hCvar_Invalid_Jump = CreateConVar("ljstats_invalid_lj", "280.0", "Cancel Jump if PRESTRAFE and DISTANCE is over this value.", FCVAR_PLUGIN);
  238.     g_hCvar_Stop_LJ = CreateConVar("ljstats_print_lj", "240.0", "Long Jump minimum units to show result to player.", FCVAR_PLUGIN);
  239.     g_hCvar_Stop_BJ = CreateConVar("ljstats_print_bj", "270.0", "Bhop Jump minimum units to show result to player.", FCVAR_PLUGIN);
  240.     g_hCvar_Stop_BUJ = CreateConVar("ljstats_print_buj", "250.0", "Bhop Up Jump minimum units to show result to player.", FCVAR_PLUGIN);
  241.     g_hCvar_Stop_Block_LJ = CreateConVar("ljstats_register_block_lj", "235.0", "Minimum units to register Block Long Jump.", FCVAR_PLUGIN);
  242.     g_hCvar_Print_LJ = CreateConVar("ljstats_show_lj", "260.0", "Print long jump result over this value.", FCVAR_PLUGIN);
  243.     g_hCvar_Print_WJ = CreateConVar("ljstats_show_wj", "270.0", "Print weird jump result over this value.", FCVAR_PLUGIN);
  244.     g_hCvar_Print_BJ = CreateConVar("ljstats_show_bj", "270.0", "Print bhop Jump result over this value.", FCVAR_PLUGIN);
  245.     g_hCvar_Print_Block_LJ = CreateConVar("ljstats_show_block_lj", "255.0", "Print Block Long Jump result over this value.", FCVAR_PLUGIN);
  246.     g_hCvar_Print_Block_BJ = CreateConVar("ljstats_show_block_bj", "275.0", "Print Block Bhop Jump result over this value.", FCVAR_PLUGIN);
  247.     g_hCvar_DB_Record = CreateConVar("ljstats_db_record", "260.0", "Record result into database over this value.", FCVAR_PLUGIN);
  248.     g_hCvar_Sound[0] = CreateConVar("ljstats_snd_impressive", "255.0", "Play Sound - impressive.", FCVAR_PLUGIN);
  249.     g_hCvar_Sound[1] = CreateConVar("ljstats_snd_perfect", "260.0", "Play Sound - perfect.", FCVAR_PLUGIN);
  250.     g_hCvar_Sound[2] = CreateConVar("ljstats_snd_wickedsick", "265.0", "Play Sound - wickedsick.", FCVAR_PLUGIN);
  251.     g_hCvar_Sound[3] = CreateConVar("ljstats_snd_godlick", "268.0", "Play Sound - godlike.", FCVAR_PLUGIN);
  252.     g_hCvar_Sound[4] = CreateConVar("ljstats_snd_holyshit", "270.0", "Play Sound - holyshit.", FCVAR_PLUGIN);
  253.     HookConVarChange(g_hCvar_Show_Message, ConVarChanged);
  254.     HookConVarChange(g_hCvar_DB, ConVarChanged);
  255.     HookConVarChange(g_hCvar_Invalid_Jump, ConVarChanged);
  256.     HookConVarChange(g_hCvar_Stop_LJ, ConVarChanged);
  257.     HookConVarChange(g_hCvar_Stop_BJ, ConVarChanged);
  258.     HookConVarChange(g_hCvar_Stop_BUJ, ConVarChanged);
  259.     HookConVarChange(g_hCvar_Stop_Block_LJ, ConVarChanged);
  260.     HookConVarChange(g_hCvar_Print_LJ, ConVarChanged);
  261.     HookConVarChange(g_hCvar_Print_WJ, ConVarChanged);
  262.     HookConVarChange(g_hCvar_Print_BJ, ConVarChanged);
  263.     HookConVarChange(g_hCvar_Print_Block_LJ, ConVarChanged);
  264.     HookConVarChange(g_hCvar_Print_Block_BJ, ConVarChanged);
  265.     HookConVarChange(g_hCvar_DB_Record, ConVarChanged);
  266.     for(new i = 0; i < sizeof(g_Sound); i++)
  267.     {
  268.         HookConVarChange(g_hCvar_Sound[i], ConVarChanged);
  269.     }
  270.     AutoExecConfig(true, "js_ljstats");
  271.     CreateTopMenu();
  272.     if(g_bLateLoaded)
  273.     {
  274.         OnAutoConfigsBuffered();
  275.         FindNHookWalls();
  276.         HookTrigger();
  277.         for(new i = 1; i <= MaxClients; i++)
  278.         {
  279.             if(IsClientInGame(i))
  280.             {
  281.                 OnClientPutInServer(i);
  282.             }
  283.         }
  284.     }
  285.    
  286.     LoadPhysics();
  287. }
  288. public OnPluginEnd()
  289. {
  290.     for(new i = 1; i<= MaxClients; i++)
  291.     {
  292.         OnClientDisconnect(i);
  293.     }
  294. }
  295. public OnAutoConfigsBuffered()
  296. {
  297.     g_ShowMsg = GetConVarInt(g_hCvar_Show_Message);
  298.     g_InvalidUnit = GetConVarFloat(g_hCvar_Invalid_Jump);
  299.     g_Stop_LJ = GetConVarFloat(g_hCvar_Stop_LJ);
  300.     g_Stop_BJ = GetConVarFloat(g_hCvar_Stop_BJ);
  301.     g_Stop_BUJ = GetConVarFloat(g_hCvar_Stop_BUJ);
  302.     g_Stop_Block_LJ = GetConVarFloat(g_hCvar_Stop_Block_LJ);
  303.     g_Print_LJ = GetConVarFloat(g_hCvar_Print_LJ);
  304.     g_Print_WJ = GetConVarFloat(g_hCvar_Print_WJ);
  305.     g_Print_BJ = GetConVarFloat(g_hCvar_Print_BJ);
  306.     g_Print_Block_LJ = GetConVarFloat(g_hCvar_Print_Block_LJ);
  307.     g_Print_Block_BJ = GetConVarFloat(g_hCvar_Print_Block_BJ);
  308.     g_DB_Record = GetConVarFloat(g_hCvar_DB_Record);
  309.     for(new i = 0; i < sizeof(g_Sound); i++)
  310.     {
  311.         g_Sound[i] = GetConVarFloat(g_hCvar_Sound[i]);
  312.     }
  313.     ConnectToDB();
  314. }
  315. public ConVarChanged(Handle:convar, const String:oldValue[], const String:newValue[])
  316. {
  317.     if(convar == g_hCvar_Show_Message)
  318.     {
  319.         g_ShowMsg = GetConVarInt(g_hCvar_Show_Message);
  320.     }
  321.     else if(convar == g_hCvar_Invalid_Jump)
  322.     {
  323.         g_InvalidUnit = GetConVarFloat(g_hCvar_Invalid_Jump);
  324.     }
  325.     else if(convar == g_hCvar_Stop_LJ)
  326.     {
  327.         g_Stop_LJ = GetConVarFloat(g_hCvar_Stop_LJ);
  328.     }
  329.     else if(convar == g_hCvar_Stop_BJ)
  330.     {
  331.         g_Stop_BJ = GetConVarFloat(g_hCvar_Stop_BJ);
  332.     }
  333.     else if(convar == g_hCvar_Stop_BUJ)
  334.     {
  335.         g_Stop_BUJ = GetConVarFloat(g_hCvar_Stop_BUJ);
  336.     }
  337.     else if(convar == g_hCvar_Stop_Block_LJ)
  338.     {
  339.         g_Stop_Block_LJ = GetConVarFloat(g_hCvar_Stop_Block_LJ);
  340.     }
  341.     else if(convar == g_hCvar_Print_LJ)
  342.     {
  343.         g_Print_LJ = GetConVarFloat(g_hCvar_Print_LJ);
  344.     }
  345.     else if(convar == g_hCvar_Print_WJ)
  346.     {
  347.         g_Print_WJ = GetConVarFloat(g_hCvar_Print_WJ);
  348.     }
  349.     else if(convar == g_hCvar_Print_BJ)
  350.     {
  351.         g_Print_BJ = GetConVarFloat(g_hCvar_Print_BJ);
  352.     }
  353.     else if(convar == g_hCvar_Print_Block_LJ)
  354.     {
  355.         g_Print_Block_LJ = GetConVarFloat(g_hCvar_Print_Block_LJ);
  356.     }
  357.     else if(convar == g_hCvar_Print_Block_BJ)
  358.     {
  359.         g_Print_Block_BJ = GetConVarFloat(g_hCvar_Print_Block_BJ);
  360.     }
  361.     else if(convar == g_hCvar_DB)
  362.     {
  363.         ConnectToDB();
  364.     }
  365.     for(new i = 0; i < sizeof(g_Sound); i++)
  366.     {
  367.         if(convar == g_hCvar_Sound[i])
  368.         {
  369.             g_Sound[i] = GetConVarFloat(g_hCvar_Sound[i]);
  370.         }
  371.     }
  372. }
  373. public OnMapStart()
  374. {
  375.     decl String:txt[256];
  376.     for(new i = 0; i < 5; i++)
  377.     {
  378.         Format(txt, 256, "sound/%s", LJ_SOUND[i]);
  379.         AddFileToDownloadsTable(txt);
  380.         PrecacheSound(LJ_SOUND[i], true);
  381.     }
  382.     g_Beam[0] = PrecacheModel("materials/sprites/laser.vmt");
  383.     g_Beam[1] = PrecacheModel("materials/sprites/halo01.vmt");
  384.    
  385.     LoadPhysics();
  386. }
  387.  
  388. public OnClientPutInServer(client)
  389. {
  390.     g_bLJmode[client] = false;
  391.     g_bLJBlock[client] = false;
  392.     g_bLJpopup[client] = true;
  393.     g_bLJplaysnd[client] = true;
  394. }
  395. public OnClientDisconnect(client)
  396. {
  397.     g_bLJmode[client] = false;
  398.     if(AimHandle[client]!=INVALID_HANDLE)
  399.     {
  400.         KillTimer(AimHandle[client]);
  401.         AimHandle[client] = INVALID_HANDLE;
  402.     }
  403. }
  404. public Action:Touch_Wall(ent,client)
  405. {
  406.     if(0 < client <= MaxClients)
  407.     {
  408.         if(PlayerReadyType[client] == ReadyType_Wj)
  409.         {
  410.             PlayerReadyType[client] = ReadyType_None;
  411.         }
  412.         if(g_bValidJump[client]&&!(GetEntityFlags(client)&FL_ONGROUND))
  413.         {
  414.             new Float:origin[3], Float:temp[3];
  415.             GetGroundOrigin(client, origin);
  416.             GetClientAbsOrigin(client, temp);
  417.             // PrintToChat(client, "\x03Client height : %f, \x04Ground height : %f", temp[2], origin[2]);
  418.             if(temp[2] - origin[2] <= 0.2)//means slope not just a wall.
  419.             {
  420.                 PrintToChat(client, "\x01[\x05LJstats\x01]\x03Jump canceled \x01: Possible surfing.");
  421.                 g_bValidJump[client] = false;
  422.                 PlayerReadyType[client] = ReadyType_None;
  423.             }
  424.         }
  425.     }
  426.     return Plugin_Continue;
  427. }
  428. public Action:event_jump(Handle:Event, const String:Name[], bool:Broadcast)
  429. {
  430.     new client = GetClientOfUserId(GetEventInt(Event, "userid"));
  431.     if(g_bLJmode[client])
  432.     {
  433.         if(PlayerReadyType[client] != ReadyType_None)
  434.         {
  435.             decl Float:temp[3], Float:origin[3];
  436.             GetEntPropVector(client, Prop_Data, "m_vecVelocity", temp);
  437.             temp[2] = 0.0;
  438.             new Float:newvelo = GetVectorLength(temp);
  439.             GetGroundOrigin(client, origin);
  440.             if(g_bLJBlock[client])
  441.             {
  442.                 GetEdgeOrigin(client, origin, temp);
  443.                 g_EdgeDist[client] = GetVectorDistance(temp, origin);
  444.             }
  445.             // PrintToChat(client, "\x03Jumped : %f", origin[2]);
  446.             new JumpType:type;
  447.             if(PlayerReadyType[client] == ReadyType_LongJump)
  448.             {
  449.                 type = JumpType_LongJump;
  450.             }
  451.             else if(PlayerReadyType[client] == ReadyType_BhopJump)
  452.             {
  453.                 type = JumpType_BhopJump;
  454.             }
  455.             else if(PlayerReadyType[client] == ReadyType_BhopUpJump)
  456.             {
  457.                 type = JumpType_BhopUpJump;
  458.             }
  459.             else if(PlayerReadyType[client] == ReadyType_Wj)
  460.             {
  461.                 type = JumpType_Wj;
  462.             }
  463.             else if(PlayerReadyType[client] == ReadyType_BlockLongJump)
  464.             {
  465.                 type = JumpType_BlockLongJump;
  466.             }
  467.             else if(PlayerReadyType[client] == ReadyType_BlockBhopJump)
  468.             {
  469.                 type = JumpType_BlockBhopJump;
  470.             }
  471.             StartJumpStats(client, type, origin, newvelo);
  472.         }
  473.     }
  474. }
  475. public Action:event_team(Handle:Event, const String:Name[], bool:Broadcast)
  476. {
  477.     new client = GetClientOfUserId(GetEventInt(Event, "userid"));
  478.     if(client != 0)
  479.     {
  480.         if(IsClientInGame(client))
  481.         {
  482.             if(GetEventInt(Event, "team")==1)
  483.             {
  484.                 g_bLJmode[client] = false;
  485.             }
  486.         }
  487.     }
  488. }
  489. public Action:event_roundstart(Handle:Event, const String:Name[], bool:Broadcast)
  490. {
  491.     FindNHookWalls();//i don't know why. but better hook after level completely loaded.
  492.     HookTrigger();
  493. }
  494. FindNHookWalls()
  495. {/**Hook wall-like entities to prevent surfing. add more entity class if missing.
  496.     also it may work just with StartTouch not Touch(haven't tried)**/
  497.     SDKHook(0,SDKHook_Touch,Touch_Wall);//World entity
  498.     new ent = -1;
  499.     while((ent = FindEntityByClassname(ent,"func_breakable")) != -1)
  500.     {
  501.         SDKHook(ent,SDKHook_Touch,Touch_Wall);
  502.     }
  503.     ent = -1;
  504.     while((ent = FindEntityByClassname(ent,"func_illusionary")) != -1)
  505.     {
  506.         SDKHook(ent,SDKHook_Touch,Touch_Wall);
  507.     }
  508.     ent = -1;
  509.     while((ent = FindEntityByClassname(ent,"func_wall")) != -1)
  510.     {
  511.         SDKHook(ent,SDKHook_Touch,Touch_Wall);
  512.     }
  513. }
  514. HookTrigger()
  515. {
  516.     new ent = -1;
  517.     while((ent = FindEntityByClassname(ent, "trigger_push")) != -1)
  518.     {
  519.         SDKHook(ent,SDKHook_Touch,Push_Touch);
  520.     }
  521. }
  522. public Action:Push_Touch(ent,client)
  523. {
  524.     if(0 < client <= MaxClients)
  525.     {
  526.         if(g_bLJmode[client])
  527.         {
  528.             g_bLJmode[client] = false;
  529.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03You touched Booster. LJmode disabled");
  530.         }
  531.     }
  532.     return Plugin_Continue;
  533. }
  534. public Action:Command_ljmode(client, args)
  535. {
  536.     if(0< client<= MaxClients)
  537.     {
  538.         if(g_bLJmode[client])
  539.         {
  540.             new Action:result = Action:API_OnLJChanged(client, false);
  541.             if(result != Plugin_Handled&&result != Plugin_Stop)
  542.             {
  543.                 g_bLJmode[client] = false;
  544.                 PrintToChat(client, "\x01[\x05LJstats\x01]\x03LJ\x01 is now turned off.");
  545.             }
  546.         }
  547.         else if(!g_bLJmode[client])
  548.         {
  549.             new Action:result = Action:API_OnLJChanged(client, true);
  550.             if(result != Plugin_Handled&&result != Plugin_Stop)
  551.             {
  552.                 new Float:gravity = GetEntityGravity(client);
  553.                 if(gravity != 0.0&&gravity!=1.0)
  554.                 {
  555.                     PrintToChat(client, "\x01[\x05LJstats\x01]\x03Can't turn LJmode on while this gravity.");
  556.                 }
  557.                 else if(!g_Physics[Timer_GetMode(client)][ModeLJStats])
  558.                 {
  559.                     PrintToChat(client, "\x01[\x05LJstats\x01]\x03Can't turn LJmode on while on this mode.");
  560.                 }
  561.                 else
  562.                 {
  563.                     g_bLJmode[client] = true;
  564.                     g_bLJBlock[client] = false;
  565.                     PrintToChat(client, "\x01[\x05LJstats\x01]\x03LJ\x01 is now turned on.");
  566.                 }
  567.             }
  568.         }
  569.     }
  570.     return Plugin_Handled;
  571. }
  572. public Action:Command_ljblock(client, args)
  573. {
  574.     if(0 < client <= MaxClients)
  575.     {
  576.         if(g_bLJmode[client])
  577.         {
  578.             LJBlockMenu(client);
  579.         }
  580.         else
  581.         {
  582.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03Turn on LongJumpStats first\x01 !lj");
  583.         }
  584.     }
  585.     return Plugin_Handled;
  586. }
  587. Function_BlockJump(client)
  588. {
  589.     decl Float:pos[3], Float:origin[3];
  590.     GetAimOrigin(client, pos);
  591.     // GetClientAbsOrigin(client, temp);
  592.     TraceClientGroundOrigin(client, origin, 100.0);
  593.     // GetGroundOrigin(client, origin);
  594.     if(FloatAbs(pos[2] - origin[2]) <= 0.002)
  595.     {
  596.         CalculateBlockGap(client, origin, pos);
  597.         GetBoxFromPoint(origin, g_OriginBlock[client]);
  598.         GetBoxFromPoint(pos, g_DestBlock[client]);
  599.         // CalculateBlockGap2(client, g_OriginBlock[client], g_DestBlock[client]);
  600.         g_fBlockHeight[client] = pos[2];
  601.     }
  602.     else
  603.     {
  604.         // GetBoxFromPoint(origin, g_OriginBlock[client]);
  605.         // GetBoxFromPoint(pos, g_DestBlock[client]);
  606.         // g_bLJBlock[client] = true;
  607.         // CalculateBlockGap2(client, g_OriginBlock[client], g_DestBlock[client]);
  608.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03Only allowed for valid long jump for now.");
  609.     }
  610. }
  611. public LJBlockHandler(Handle:menu, MenuAction:action, client, select)
  612. {
  613.     if(action == MenuAction_Select)
  614.     {
  615.         if(select == 0)
  616.         {
  617.             Function_BlockJump(client);
  618.             LJBlockMenu(client);
  619.         }
  620.         else if(select == 1)
  621.         {
  622.             g_bLJBlock[client] = false;
  623.             LJBlockMenu(client);
  624.         }
  625.     }
  626.     else if(action == MenuAction_Cancel)
  627.     {
  628.         if(select == MenuCancel_Exit)
  629.         {
  630.         }
  631.     }
  632.     else if(action == MenuAction_End)
  633.     {
  634.     }
  635. }
  636. CalculateBlockGap(client, Float:origin[3], Float:target[3])
  637. {
  638.     new Float:distance = GetVectorDistance(origin, target);
  639.     new Float:rad = DegToRad(15.0);
  640.     new Float:newdistance = FloatDiv(distance, Cosine(rad));
  641.     decl Float:eye[3], Float:eyeangle[2][3];
  642.     new Float:temp = 0.0;
  643.     GetClientEyePosition(client, eye);
  644.     GetClientEyeAngles(client, eyeangle[0]);
  645.     eyeangle[0][0] = 0.0;
  646.     eyeangle[1] = eyeangle[0];
  647.     eyeangle[0][1] += 10.0;
  648.     eyeangle[1][1] -= 10.0;
  649.     decl Float:position[3], Float:ground[3], Float:Last[2], Float:Edge[2][3];
  650.     new bool:edgefound[2];
  651.     while(temp < newdistance)
  652.     {
  653.         temp += 10.0;
  654.         for(new i = 0; i < 2 ; i++)
  655.         {
  656.             if(edgefound[i])
  657.                 continue;
  658.             GetBeamEndOrigin(eye, eyeangle[i], temp, position);
  659.             TraceGroundOrigin(position, ground);
  660.             if(temp == 10.0)
  661.             {
  662.                 Last[i] = ground[2];
  663.             }
  664.             else
  665.             {
  666.                 if((Last[i] != ground[2])&&(Last[i] > ground[2]))
  667.                 {
  668.                     Edge[i] = ground;
  669.                     edgefound[i] = true;
  670.                 }
  671.                 Last[i] = ground[2];
  672.             }
  673.         }
  674.     }
  675.     decl Float:temp2[2][3];
  676.     if(edgefound[0] && edgefound[1])
  677.     {
  678.         for(new i = 0; i < 2 ; i++)
  679.         {
  680.             temp2[i] = Edge[i];
  681.             temp2[i][2] = origin[2] - 1.0;
  682.             if(eyeangle[i][1] > 0)
  683.             {
  684.                 eyeangle[i][1] -= 180.0;
  685.             }
  686.             else
  687.             {
  688.                 eyeangle[i][1] += 180.0;
  689.             }
  690.             GetBeamHitOrigin(temp2[i], eyeangle[i], Edge[i]);
  691.         }
  692.     }
  693.     else
  694.     {
  695.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03Invalid Block");
  696.         return;
  697.     }
  698.     g_EdgePoint[client] = Edge[0];
  699.     TE_SetupBeamPoints(Edge[0], Edge[1], g_Beam[0], 0, 0, 0, 10.0, 1.0, 1.0, 10, 0.0, {0,255,255,212}, 0);
  700.     TE_SendToAll();
  701.     MakeVectorFromPoints(Edge[0], Edge[1], position);
  702.     g_EdgeVector[client] = position;
  703.     NormalizeVector(g_EdgeVector[client], g_EdgeVector[client]);
  704.     CorrectEdgePoint(client);
  705.     GetVectorAngles(position, position);
  706.     position[1] += 90.0;
  707.     GetBeamHitOrigin(Edge[0], position, Edge[1]);
  708.     TE_SetupBeamPoints(Edge[0], Edge[1], g_Beam[0], 0, 0, 0, 10.0, 1.0, 1.0, 10, 0.0, {0,255,255,212}, 0);
  709.     TE_SendToAll();
  710.     distance = GetVectorDistance(Edge[0], Edge[1]);
  711.     g_BlockDist[client] = RoundToNearest(distance);
  712.     if(g_BlockDist[client] >= g_Stop_Block_LJ)
  713.     {
  714.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03%d Unit Block registered (\x01ß\x03)", g_BlockDist[client]);
  715.         g_bLJBlock[client] = true;
  716.     }
  717.     else
  718.     {
  719.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03You can regiter block more than %.0f units.", g_Stop_Block_LJ);
  720.     }
  721. }
  722. stock CalculateBlockGap2(client, Float:origin[2][3], Float:target[2][3])
  723. {
  724.     decl Float:temp[2][3];
  725.     decl Float:edge[2][3], Float:result[3];
  726.     if(origin[1][0] > target[0][0])
  727.     {
  728.         if(origin[0][1] < target[1][0])
  729.         {
  730.             PrintToChat(client, "1-a");
  731.             temp[0] = origin[1];
  732.             temp[0][1] = origin[0][1];
  733.             temp[1] = target[0];
  734.             temp[1][0] = target[1][0];
  735.             g_BlockDist[client] = RoundToNearest(GetVectorDistance(temp[0], temp[1]));
  736.         }
  737.         else if(origin[1][1] > target[0][1])
  738.         {
  739.             PrintToChat(client, "1-b");
  740.             temp[0] = origin[1];
  741.             temp[1] = target[0];
  742.             g_BlockDist[client] = RoundToNearest(GetVectorDistance(temp[0], temp[1]));
  743.         }
  744.         else
  745.         {
  746.             PrintToChat(client, "1-e");
  747.             edge[0] = origin[1];
  748.             edge[0][1] = origin[0][1];
  749.             edge[1] = origin[1];
  750.             GetGapVector(edge, result, -90.0);
  751.             PrintToChat(client, "%f %f %f", result[0], result[1], result[2]);
  752.         }
  753.     }
  754.     else if(origin[0][0] < target[1][0])
  755.     {
  756.         if(origin[0][1] < target[1][1])
  757.         {
  758.             PrintToChat(client, "1-c");
  759.             temp[0] = origin[0];
  760.             temp[1] = target[1];
  761.             g_BlockDist[client] = RoundToNearest(GetVectorDistance(temp[0], temp[1]));
  762.         }
  763.         else if(origin[1][1] > target[0][1])
  764.         {
  765.             PrintToChat(client, "1-d");
  766.             temp[0] = origin[0];
  767.             temp[0][1] = origin[1][1];
  768.             temp[1] = target[1];
  769.             temp[1][1] = target[0][1];
  770.             g_BlockDist[client] = RoundToNearest(GetVectorDistance(temp[0], temp[1]));
  771.         }
  772.         else
  773.         {
  774.             PrintToChat(client, "1-f");
  775.             edge[0] = origin[1];
  776.             edge[0][1] = origin[0][1];
  777.             edge[1] = origin[1];
  778.             GetGapVector(edge, result, 90.0);
  779.             PrintToChat(client, "%f %f %f", result[0], result[1], result[2]);
  780.         }
  781.     }
  782.     else
  783.     {
  784.         if(origin[1][1] > target[0][1])
  785.         {
  786.             PrintToChat(client, "1-g");
  787.             edge[0] = origin[0];
  788.             edge[1] = origin[0];
  789.             edge[1][0] = origin[1][0];
  790.             GetGapVector(edge, result, 90.0);
  791.             PrintToChat(client, "%f %f %f", result[0], result[1], result[2]);
  792.         }
  793.         else if(origin[0][1] < target[1][1])
  794.         {
  795.             PrintToChat(client, "1-h");
  796.             edge[0] = origin[0];
  797.             edge[1] = origin[0];
  798.             edge[1][0] = origin[1][0];
  799.             GetGapVector(edge, result, -90.0);
  800.             GetBoxGap
  801.             if(target[1][0] <= origin[1][0] <= target[0][0])
  802.             {
  803.                 temp[0][0] = GetRandomFloat(origin[1][0], target[0][0]);
  804.             }
  805.             else if(target[1][0] <= origin[0][0] <= target[0][0])
  806.             {
  807.                 temp[0][0] = GetRandomFloat(target[1][0], origin[0][0]);
  808.             }
  809.             else
  810.             {
  811.                 PrintToChat(client, "??");
  812.             }
  813.             temp[0] = origin[0];
  814.             temp[0][2] -= 1.0;
  815.             PrintToChat(client, "%f %f %f", temp[0][0], temp[0][1], temp[0][2]);
  816.             PrintToChat(client, "%f %f %f", result[0], result[1], result[2]);
  817.             GetBeamHitOrigin(temp[0], result, temp[1]);
  818.             PrintToChat(client, "%f %f %f", temp[0][0], temp[0][1], temp[0][2]);
  819.             PrintToChat(client, "%f %f %f", temp[1][0], temp[1][1], temp[1][2]);
  820.             g_BlockDist[client] = RoundToNearest(GetVectorDistance(temp[0], temp[1]));
  821.         }
  822.     }
  823.    
  824.     if(g_BlockDist[client] >= g_Stop_Block_LJ)
  825.     {
  826.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03%d Unit Block registered (\x01ß\x03)", g_BlockDist[client]);
  827.         g_bLJBlock[client] = true;
  828.     }
  829.     else
  830.     {
  831.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03You can regiter block more than %.0f units. (\x01ß\x03)", g_Stop_Block_LJ);
  832.     }
  833.     TE_SetupBeamPoints(origin[0], origin[1], g_Beam[0], 0, 0, 0, 10.0, 1.0, 1.0, 10, 0.0, {0,255,255,212}, 0);
  834.     TE_SendToAll();
  835.     TE_SetupBeamPoints(target[0], target[1], g_Beam[0], 0, 0, 0, 10.0, 1.0, 1.0, 10, 0.0, {0,255,255,212}, 0);
  836.     TE_SendToAll();
  837.     TE_SetupBeamPoints(temp[0], temp[1], g_Beam[0], 0, 0, 0, 10.0, 1.0, 1.0, 10, 0.0, {0,255,255,212}, 0);
  838.     TE_SendToAll();
  839. }
  840. GetEdgeOrigin(client, Float:ground[3], Float:result[3])
  841. {
  842.     result[0] = FloatDiv(g_EdgeVector[client][0]*ground[0] + g_EdgeVector[client][1]*g_EdgePoint[client][0], g_EdgeVector[client][0]+g_EdgeVector[client][1]);
  843.     result[1] = FloatDiv(g_EdgeVector[client][1]*ground[1] - g_EdgeVector[client][0]*g_EdgePoint[client][1], g_EdgeVector[client][1]-g_EdgeVector[client][0]);
  844.     result[2] = ground[2];
  845. }
  846. CorrectEdgePoint(client)
  847. {
  848.     decl Float:vec[3];
  849.     vec[0] = 0.0 - g_EdgeVector[client][1];
  850.     vec[1] = g_EdgeVector[client][0];
  851.     vec[2] = 0.0;
  852.     ScaleVector(vec, 16.0);
  853.     AddVectors(g_EdgePoint[client], vec, g_EdgePoint[client]);
  854. }
  855. API_OnLJChanged(client, bool:on)
  856. {
  857.     decl Action:result;
  858.     Call_StartForward(g_LJMode_Forward);
  859.     Call_PushCell(client);
  860.     Call_PushCell(on);
  861.     Call_Finish(_:result);
  862.     return _:result;
  863. }
  864. public Action:Command_ljsound(client, args)
  865. {
  866.     if(0 < client <= MaxClients)
  867.     {
  868.         if(g_bLJplaysnd[client])
  869.         {
  870.             g_bLJplaysnd[client] = false;
  871.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03Sound \x01off.");
  872.         }
  873.         else
  874.         {
  875.             g_bLJplaysnd[client] = true;
  876.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03Sound \x01on.");
  877.         }
  878.     }
  879.     return Plugin_Handled;
  880. }
  881. public Action:Command_ljpopup(client, args)
  882. {
  883.     if(0 < client <= MaxClients)
  884.     {
  885.         if(g_bLJpopup[client])
  886.         {
  887.             g_bLJpopup[client] = false;
  888.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03Popup \x01off.");
  889.         }
  890.         else
  891.         {
  892.             g_bLJpopup[client] = true;
  893.             PrintToChat(client, "\x01[\x05LJstats\x01]\x03Popup \x01on.");
  894.         }
  895.     }
  896.     return Plugin_Handled;
  897. }
  898. public Action:Command_measure(client, args)
  899. {
  900.     if(0 < client <= MaxClients)
  901.     {
  902.         for(new i = 0; i < 3; i++)
  903.         {
  904.             AimPoint_1[client][i] = 0.0;
  905.             AimPoint_2[client][i] = 0.0;
  906.         }
  907.         AimStatus[client] = 0;
  908.         AimMenu(client);
  909.     }
  910.     return Plugin_Handled;
  911. }
  912. AimMenu(client)
  913. {
  914.     new Handle:menu = CreateMenu(AimMenu_Handler);
  915.     SetMenuTitle(menu, "Measure");
  916.     if(AimStatus[client] == 0)
  917.         AddMenuItem(menu, "0", "Select 1st point");
  918.     else if(AimStatus[client] == 1)
  919.         AddMenuItem(menu, "0", "Select 2nd point");
  920.     else
  921.         AddMenuItem(menu, "0", "measure it!");
  922.     DisplayMenu(menu, client, MENU_TIME_FOREVER);
  923. }
  924. public AimMenu_Handler(Handle:menu, MenuAction:click, client, select)
  925. {
  926.     if(click == MenuAction_Select)
  927.     {
  928.         if(AimStatus[client] == 0)
  929.         {
  930.             GetAimOrigin(client, AimPoint_1[client]);
  931.             AimDrawing[client] = true;
  932.             AimStatus[client] = 1;
  933.             if(AimHandle[client]!=INVALID_HANDLE)
  934.             {
  935.                 KillTimer(AimHandle[client]);
  936.                 AimHandle[client] = INVALID_HANDLE;
  937.             }
  938.             AimHandle[client] = CreateTimer(0.1, Draw_Aim, client, TIMER_REPEAT);
  939.         }
  940.         else if(AimStatus[client] == 1)
  941.         {
  942.             GetAimOrigin(client, AimPoint_2[client]);
  943.             AimDrawing[client] = true;
  944.             AimStatus[client] = 2;
  945.         }
  946.         else
  947.         {
  948.             AimStatus[client] = 0;
  949.             MeasurePoint(client, AimPoint_1[client], AimPoint_2[client]);
  950.         }
  951.         AimMenu(client);
  952.     }
  953.     else if(click == MenuAction_Cancel)
  954.     {
  955.         if(select == MenuCancel_ExitBack)
  956.         {
  957.         }
  958.         if(select == MenuCancel_Exit)
  959.         {
  960.         }
  961.     }
  962.     else if(click == MenuAction_End)
  963.     {
  964.         CloseHandle(menu);
  965.     }
  966. }
  967. stock MeasurePoint(client, const Float:pos1[3], const Float:pos2[3])
  968. {
  969.     decl Float:height, Float:width, Float:length;
  970.     height = FloatAbs(pos1[2] - pos2[2]);
  971.     width = SquareRoot((pos2[0] - pos1[0])*(pos2[0] - pos1[0]) + (pos2[1] - pos1[1])*(pos2[1] - pos1[1]));
  972.     length = GetVectorDistance(pos1, pos2);
  973.     PrintToChat(client, "\x01[\x05LJstats\x01]\x03%.2f units, width : %.2f units, height : %.2f units", length, width, height);
  974.     CreateTimer(2.0, Reset_Drawing_Aim, client);
  975. }
  976. public Action:Draw_Aim(Handle:timer, any:client)
  977. {
  978.     if(IsClientInGame(client))
  979.     {
  980.         new Float:origin1[3], Float:origin2[3];
  981.         if(AimStatus[client] == 1)
  982.         {
  983.             origin1 = AimPoint_1[client];
  984.             GetAimOrigin(client, origin2);
  985.         }
  986.         else
  987.         {
  988.             origin1 = AimPoint_1[client];
  989.             origin2 = AimPoint_2[client];
  990.         }
  991.         TE_SetupBeamPoints(origin1, origin2, g_Beam[0], 0, 0, 0, 0.1, 3.0, 3.0, 10, 0.0, {125,125,125,255}, 0);
  992.         TE_SendToClient(client);
  993.         return Plugin_Continue;
  994.     }
  995.     else
  996.     {
  997.         return Plugin_Stop;
  998.     }
  999. }  
  1000. public Action:Reset_Drawing_Aim(Handle:timer, any:client)
  1001. {
  1002.     if(AimHandle[client]!=INVALID_HANDLE)
  1003.     {
  1004.         KillTimer(AimHandle[client]);
  1005.         AimHandle[client] = INVALID_HANDLE;
  1006.     }
  1007. }
  1008. public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
  1009. {
  1010.     static bool:OnLastGround[MAXPLAYERS + 1], Float:HintTimer[MAXPLAYERS + 1], Float:LastPosition[MAXPLAYERS + 1][3], Float:LastVelocity[MAXPLAYERS + 1], LastButton[MAXPLAYERS + 1], LastStrafe[MAXPLAYERS + 1], Float:LastAngle[MAXPLAYERS + 1], bool:MovingLeft[MAXPLAYERS + 1], bool:MovingRight[MAXPLAYERS + 1], MoveType:LastMoveType[MAXPLAYERS + 1];
  1011.     if(IsClientInGameAlive(client))
  1012.     {
  1013.         if(g_bLJmode[client])
  1014.         {
  1015.             new Float:temp[3], Float:origin[3];
  1016.             GetEntPropVector(client, Prop_Data, "m_vecVelocity", temp);
  1017.             temp[2] = 0.0;
  1018.             new Float:newvelo = GetVectorLength(temp);
  1019.             GetClientAbsOrigin(client, origin);
  1020.             new MoveType:movetype = GetEntityMoveType(client);
  1021.             new Float:ang[3];
  1022.             GetClientEyeAngles(client, ang);
  1023.             if(ang[1] < 0)
  1024.             {
  1025.                 ang[1] += 360.0;
  1026.             }
  1027.             if(GetEntityFlags(client)&FL_ONGROUND)
  1028.             {//?????
  1029.                 if(!OnLastGround[client])
  1030.                 {//?? ????.
  1031.                     OnGroundTime[client] = GetGameTime();
  1032.                     if(g_bValidJump[client])
  1033.                     {//?????.
  1034.                         GetGroundOrigin(client, g_fOnGroundPos[client]);
  1035.                         if(GetEntityFlags(client)&FL_DUCKING)
  1036.                         {
  1037.                             NoDucking[client] = false;
  1038.                             // g_fOnGroundPos[client][2] += 0.68;
  1039.                         }
  1040.                         else
  1041.                         {
  1042.                             NoDucking[client] = true;
  1043.                         }
  1044.                         LJStats(client, false);
  1045.                         g_bValidJump[client] = false;
  1046.                     }
  1047.                 }
  1048.                 else
  1049.                 {
  1050.  
  1051.                     if(GetGameTime() >= OnGroundTime[client] + LJDELAY)
  1052.                     {
  1053.                         if(PlayerReadyType[client] != ReadyType_LongJump && PlayerReadyType[client] != ReadyType_BlockLongJump)
  1054.                         {
  1055.                             PlayerReadyType[client] = ReadyType_LongJump;
  1056.                         }
  1057.                     }
  1058.                     else if(GetGameTime() >= OnGroundTime[client] + ELSEDELAY)
  1059.                     {
  1060.                         PlayerReadyType[client] = ReadyType_None;
  1061.                     }
  1062.                 }
  1063.                 if(GetGameTime() >= HintTimer[client])
  1064.                 {
  1065.                     if(PlayerReadyType[client] == ReadyType_LongJump||PlayerReadyType[client] == ReadyType_BlockLongJump)
  1066.                     {
  1067.                         HintTimer[client] = GetGameTime() + 0.1;
  1068.                         decl Float:edge[3], Float:dist, Float:ground[3], String:edgeinfo[64];
  1069.                         edgeinfo[0] = '\0';
  1070.                         if(g_bLJBlock[client])
  1071.                         {
  1072.                             GetGroundOrigin(client, ground);
  1073.                             GetEdgeOrigin(client, ground, edge);
  1074.                             dist = GetVectorDistance(edge, ground);
  1075.                             Format(edgeinfo, sizeof(edgeinfo), "\nEdge : %.3f", dist);
  1076.                             TE_SendBlockPoint(client, g_DestBlock[client][0], g_DestBlock[client][1], g_Beam[0]);
  1077.                             TE_SendBlockPoint(client, g_OriginBlock[client][0], g_OriginBlock[client][1], g_Beam[0]);
  1078.                             // TE_SetupBeamPoints(ground, trueground, g_Beam[0], 0, 0, 0, 0.13, 5.0, 2.0, 10, 0.0, {255, 254, 125, 255}, 0);
  1079.                             // TE_SendToClient(client);
  1080.                             if(!IsCoordInBlockPoint(ground, g_OriginBlock[client]))
  1081.                             {
  1082.                                 Format(edgeinfo, sizeof(edgeinfo), "");
  1083.                             }
  1084.                             else
  1085.                             {
  1086.                                 PlayerReadyType[client] = ReadyType_BlockLongJump;
  1087.                             }
  1088.                         }
  1089.                        
  1090.                         Client_PrintHintText(client, "Prestrafe\n%.2f%s", newvelo, edgeinfo);
  1091.                         for (new i = 1; i <= MaxClients; i++)
  1092.                         {
  1093.                             if (IsClientInGame(i))
  1094.                             {
  1095.                                 if(!IsPlayerAlive(i) || IsClientObserver(i))
  1096.                                 {
  1097.                                     new iObserverMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
  1098.                                     if(iObserverMode == SPECMODE_FIRSTPERSON || iObserverMode == SPECMODE_3RDPERSON)
  1099.                                     {
  1100.                                         new target = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
  1101.                                        
  1102.                                         if(target != client || target == i)
  1103.                                             continue;
  1104.                                        
  1105.                                         if(target <= 0 || target > MaxClients)
  1106.                                             continue;
  1107.                                        
  1108.                                         Client_PrintHintText(i, "Prestrafe\n%.2f%s", newvelo, edgeinfo);
  1109.                                     }
  1110.                                     else
  1111.                                     {
  1112.                                         continue;
  1113.                                     }
  1114.                                 }
  1115.                             }
  1116.                         }
  1117.                     }
  1118.                 }
  1119.                 LastStrafe[client] = 0;
  1120.                 OnLastGround[client] = true;
  1121.             }
  1122.             else
  1123.             {//?? ???
  1124.                 if(movetype == MOVETYPE_WALK)
  1125.                 {
  1126.                     if(LastMoveType[client] == MOVETYPE_LADDER)
  1127.                     {
  1128.                         StartJumpStats(client, JumpType_Ladder, LastPosition[client], LastVelocity[client]);
  1129.                     }
  1130.                     else
  1131.                     {
  1132.                         if(!g_bValidJump[client])
  1133.                         {
  1134.                             if(OnLastGround[client])
  1135.                             {//?? ?? ?????.
  1136.                                 if(!(LastButton[client]&IN_JUMP))
  1137.                                 {
  1138.                                     PlayerReadyType[client] = ReadyType_Wj;
  1139.                                 }
  1140.                             }
  1141.                         }
  1142.                         else
  1143.                         {//??? ?????.
  1144.                             if(GetEntityFlags(client)&FL_INWATER)
  1145.                             {
  1146.                                 g_bValidJump[client] = false;
  1147.                                 PrintToChat(client, "\x01[\x05LJstats\x01]\x03Jump canceled \x01: Swimming.");
  1148.                             }
  1149.                             new Float:pos[3];
  1150.                             GetGroundOrigin2(client, pos);
  1151.                             if(ang[1] > LastAngle[client])
  1152.                             {
  1153.                                 MovingLeft[client] = true;
  1154.                                 MovingRight[client] = false;
  1155.                             }
  1156.                             else if(ang[1] < LastAngle[client])
  1157.                             {
  1158.                                 MovingLeft[client] = false;
  1159.                                 MovingRight[client] = true;
  1160.                             }
  1161.                             else
  1162.                             {
  1163.                                 MovingLeft[client] = false;
  1164.                                 MovingRight[client] = false;
  1165.                             }
  1166.                             if(newvelo > LJ_MaxSpeed[client])
  1167.                             {
  1168.                                 LJ_MaxSpeed[client] = newvelo;
  1169.                             }
  1170.                             if((buttons & IN_MOVELEFT)&&(!(buttons & IN_MOVERIGHT))&&!(LastStrafe[client]&IN_MOVELEFT))
  1171.                             {
  1172.                                 g_Strafe[client]++;
  1173.                                 LastStrafe[client] = IN_MOVELEFT;
  1174.                             }
  1175.                             else if((buttons & IN_MOVERIGHT)&&(!(buttons&IN_MOVELEFT))&&!(LastStrafe[client]&IN_MOVERIGHT))
  1176.                             {
  1177.                                 g_Strafe[client]++;
  1178.                                 LastStrafe[client] = IN_MOVERIGHT;
  1179.                             }
  1180.                             if(MAXSTR > g_Strafe[client] > 0)
  1181.                             {
  1182.                                 if(newvelo > LJ_MaxSpeedStrafe[client][g_Strafe[client]-1])
  1183.                                     LJ_MaxSpeedStrafe[client][g_Strafe[client]-1] = newvelo;
  1184.                                 if(MovingLeft[client]||MovingRight[client])
  1185.                                 {
  1186.                                     if(LastVelocity[client] < newvelo)
  1187.                                     {
  1188.                                         LJ_GoodSync[client][g_Strafe[client]-1]++;
  1189.                                         LJ_Gains[client][g_Strafe[client]-1] += (newvelo - LastVelocity[client]);
  1190.                                     }
  1191.                                     else
  1192.                                     {
  1193.                                         LJ_Lost[client][g_Strafe[client]-1] += (LastVelocity[client] - newvelo);
  1194.                                     }
  1195.                                 }
  1196.                                 LJ_Frame[client][g_Strafe[client]-1]++;
  1197.                             }
  1198.                             LJ_TotalFrame[client]++;
  1199.                             if(g_bLJBlock[client])
  1200.                             {
  1201.                                 if(origin[2] <= g_fBlockHeight[client])
  1202.                                 {
  1203.                                     // GetClientAbsOrigin(client, g_fOnGroundPos[client]);
  1204.                                     g_fOnGroundPos[client] = origin;
  1205.                                     g_fOnGroundPos[client][2] = g_fBlockHeight[client];
  1206.                                     LJStats(client, true);
  1207.                                     g_bValidJump[client] = false;
  1208.                                 }
  1209.                             }
  1210.                         }
  1211.                     }
  1212.                 }
  1213.                 OnLastGround[client] = false;
  1214.             }
  1215.             new Float:distance = GetVectorDistance(LastPosition[client], origin);
  1216.             if(distance > 25.0)
  1217.             {
  1218.                 if(g_bValidJump[client])
  1219.                 {
  1220.                     g_bValidJump[client] = false;
  1221.                 }
  1222.             }
  1223.             LastAngle[client] = ang[1];
  1224.             LastMoveType[client] = movetype;
  1225.             LastVelocity[client] = newvelo;
  1226.             LastPosition[client] = origin;
  1227.             LastButton[client] = buttons;
  1228.         }
  1229.     }
  1230. }
  1231. ResetLJStats(client)
  1232. {
  1233.     g_Strafe[client] = 0;
  1234.     LJ_MaxSpeed[client] = 0.0;
  1235.     LJ_TotalFrame[client] = 0;
  1236.     for(new i = 0; i < MAXSTR; i++)
  1237.     {
  1238.         LJ_Gains[client][i] = 0.0;
  1239.         LJ_Lost[client][i] = 0.0;
  1240.         LJ_Frame[client][i] = 0;
  1241.         LJ_GoodSync[client][i] = 0;
  1242.         LJ_BadSync[client][i] = 0;
  1243.         LJ_SyncRateStrafe[client][i] = 0.0;
  1244.         LJ_MaxSpeedStrafe[client][i] = 0.0;
  1245.     }
  1246. }
  1247. StartJumpStats(client, JumpType:type, Float:pos[3], Float:vel)
  1248. {
  1249.     decl String:weapon_name[64];
  1250.     GetClientWeapon(client, weapon_name, sizeof(weapon_name));
  1251.     if(StrEqual(weapon_name, "weapon_scout")||strlen(weapon_name)==0)
  1252.     {
  1253.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03Wrong : \x01Check your weapon.");
  1254.         return;
  1255.     }
  1256.     new Float:gravity = GetEntityGravity(client);
  1257.     if(gravity != 0.0&&gravity!=1.0)
  1258.     {
  1259.         g_bLJmode[client] = false;
  1260.         PrintToChat(client, "\x01[\x05LJstats\x01]\x03LJmode disabled : \x01Check Gravity.");
  1261.     }
  1262.     ResetLJStats(client);
  1263.     g_fJumpedPos[client] = pos;
  1264.     PreStrafe[client] = vel;
  1265.     g_bValidJump[client] = true;
  1266.     PlayerJumpType[client] = type;
  1267.     PlayerReadyType[client] = ReadyType_None;
  1268.     decl String:msg[512];
  1269.     Format(msg, 512, "Prestrafe\n%.2f", PreStrafe[client]);
  1270.     if(g_bLJBlock[client])
  1271.     {
  1272.         if(!IsCoordInBlockPoint(pos, g_OriginBlock[client]))
  1273.         {
  1274.             g_bValidJump[client] = false;
  1275.             return;
  1276.         }
  1277.         Format(msg, 512, "%s\nEdge : %f", msg, g_EdgeDist[client]);
  1278.     }
  1279.  
  1280.     Client_PrintHintText(client, msg);
  1281.    
  1282.     for (new i = 1; i <= MaxClients; i++)
  1283.     {
  1284.         if (IsClientInGame(i))
  1285.         {
  1286.             if(!IsPlayerAlive(i) || IsClientObserver(i))
  1287.             {
  1288.                 new iObserverMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
  1289.                 if(iObserverMode == SPECMODE_FIRSTPERSON || iObserverMode == SPECMODE_3RDPERSON)
  1290.                 {
  1291.                     new target = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
  1292.                    
  1293.                     if(target != client || target == i)
  1294.                         continue;
  1295.                    
  1296.                     if(target <= 0 || target > MaxClients)
  1297.                         continue;
  1298.                    
  1299.                     Client_PrintHintText(i, msg);
  1300.                 }
  1301.                 else
  1302.                 {
  1303.                     continue;
  1304.                 }
  1305.             }
  1306.         }
  1307.     }
  1308. }
  1309. public Action:LJStats(client, bool:fail)
  1310. {
  1311.     decl Float:LJ_FrameRate[MAXSTR];
  1312.     for(new i = 0; i < g_Strafe[client]; i++)
  1313.     {
  1314.         if(i < MAXSTR)
  1315.         {
  1316.             LJ_SyncRateStrafe[client][i] = (LJ_GoodSync[client][i]*100.0/LJ_Frame[client][i]);
  1317.             LJ_FrameRate[i] = LJ_Frame[client][i]*100.0/LJ_TotalFrame[client];
  1318.         }
  1319.     }
  1320.     new JumpType:J_type = PlayerJumpType[client];
  1321.     new Float:temp1[3], Float:temp2[3];
  1322.     temp1 = g_fJumpedPos[client];
  1323.     temp2 = g_fOnGroundPos[client];
  1324.     if(fail)
  1325.     {
  1326.         temp2[2] = g_fJumpedPos[client][2];
  1327.     }
  1328.     // PrintToChat(client, "\x04landed : %f", temp2[2]);
  1329.     // temp1[2] = 0.0;
  1330.     // temp2[2] = 0.0;
  1331.     new Float:distance, Float:blockdistance;
  1332.     if(fail)
  1333.     {
  1334.         distance = GetVectorDistance(temp1, temp2) + 32.0 - g_EdgeDist[client];
  1335.     }
  1336.     else
  1337.     {
  1338.         distance = GetVectorDistance(temp1, temp2) + 32.0;
  1339.     }
  1340.     LJ_SyncRate[client] = 0.0;
  1341.     new good, total;
  1342.     for(new i = 0; i <= g_Strafe[client]; i++)
  1343.     {
  1344.         if(i < MAXSTR)
  1345.         {
  1346.             good += LJ_GoodSync[client][i];
  1347.             total += LJ_Frame[client][i];
  1348.         }
  1349.     }
  1350.     LJ_SyncRate[client] = good*100.0/total;
  1351.     if(J_type != JumpType_Ladder)
  1352.     {/**Compare jumped and landed heights. although tried to get correct z-coord by custom function. still has an error.
  1353.         0.002 value determined with no reason.**/
  1354.         if((temp1[2] - temp2[2]) > 0.002)
  1355.         {
  1356.             if(J_type == JumpType_Wj)
  1357.             {
  1358.                 J_type = JumpType_WjDrop;
  1359.             }
  1360.             else
  1361.             {
  1362.                 if(J_type!=JumpType_BhopJump&&J_type!=JumpType_BhopUpJump)
  1363.                 {
  1364.                     J_type = JumpType_DropJump;
  1365.                 }
  1366.                 else
  1367.                 {
  1368.                     return Plugin_Handled;
  1369.                 }
  1370.             }
  1371.         }
  1372.         else if((temp2[2] - temp1[2]) > 0.002)
  1373.         {
  1374.             if(J_type == JumpType_Wj)
  1375.             {
  1376.                 J_type = JumpType_WjUp;
  1377.             }
  1378.             else
  1379.             {
  1380.                 if(J_type != JumpType_WjUp && J_type != JumpType_BhopUpJump)
  1381.                 {
  1382.                     J_type = JumpType_UpJump;
  1383.                     PlayerReadyType[client] = ReadyType_BhopUpJump;
  1384.                 }
  1385.                 else
  1386.                 {
  1387.                     return Plugin_Handled;
  1388.                 }
  1389.             }
  1390.         }
  1391.         else
  1392.         {
  1393.             if(J_type == JumpType_LongJump)
  1394.             {
  1395.                 PlayerReadyType[client] = ReadyType_BhopJump;
  1396.                 if(PreStrafe[client] >= g_InvalidUnit||distance >= g_InvalidUnit)
  1397.                 {
  1398.                     PrintToChat(client, "\x01[\x05LJstats\x01]\x03Wrong jump.");
  1399.                     return Plugin_Handled;
  1400.                 }
  1401.                 if(distance <= g_Stop_LJ && !fail)
  1402.                 {
  1403.                     return Plugin_Handled;
  1404.                 }
  1405.             }
  1406.             else if(J_type == JumpType_BlockLongJump&&!fail)
  1407.             {
  1408.                 if(!IsCoordInBlockPoint(temp2, g_DestBlock[client]))
  1409.                 {
  1410.                     if(IsCoordInBlockPoint(temp2, g_OriginBlock[client]))
  1411.                     {
  1412.                         PlayerReadyType[client] = ReadyType_BlockBhopJump;
  1413.                     }
  1414.                     return Plugin_Handled;
  1415.                 }
  1416.                 else
  1417.                 {
  1418.                     blockdistance = float(g_BlockDist[client]);
  1419.                 }
  1420.             }
  1421.             else if(J_type == JumpType_BlockBhopJump&&!fail)
  1422.             {
  1423.                 if(!IsCoordInBlockPoint(temp2, g_DestBlock[client]))
  1424.                 {
  1425.                     return Plugin_Handled;
  1426.                 }
  1427.                 else
  1428.                 {
  1429.                     blockdistance = float(g_BlockDist[client]);
  1430.                 }
  1431.             }
  1432.             else if(J_type == JumpType_BhopJump)
  1433.             {
  1434.                 if(distance < g_Stop_BJ)
  1435.                 {
  1436.                     return Plugin_Handled;
  1437.                 }
  1438.             }
  1439.             else if(J_type == JumpType_BhopUpJump)
  1440.             {
  1441.                 if(distance < g_Stop_BUJ)
  1442.                 {
  1443.                     return Plugin_Handled;
  1444.                 }
  1445.             }
  1446.         }
  1447.     }
  1448.     if(distance < 200.0)
  1449.     {
  1450.         return Plugin_Handled;
  1451.     }
  1452.     new Handle:menu = CreateMenu(emptyhandler);
  1453.     decl String:desc[1024], String:postfix[15], String:hint[255], String:num[5], String:max[50], String:gain[50], String:lose[50], String:sync[50], String:framerate[50], String:cns[1024], String:edge[40], Float:width, Float:height;
  1454.     edge[0] = '\0';
  1455.     Format(desc, 1024, "%s", JumpName[J_type]);
  1456.     postfix[0] = '\0';
  1457.     if(fail)
  1458.     {
  1459.         Format(desc, 1024, "%s (Failed)", desc);
  1460.         Format(postfix, sizeof(postfix), "(Failed)");
  1461.         Format(edge, sizeof(edge), ", Edge : %.3f", g_EdgeDist[client]);
  1462.     }
  1463.     else
  1464.     {
  1465.         if(g_bLJBlock[client])
  1466.         {
  1467.             Format(edge, sizeof(edge), ", Edge : %.3f", g_EdgeDist[client]);
  1468.             g_bLJBlock[client] = false;
  1469.         }
  1470.     }
  1471.     Format(desc, sizeof(desc), "%s%s", desc, edge);
  1472.     if(J_type == JumpType_Ladder)
  1473.     {
  1474.         width = SquareRoot((temp2[0] - temp1[0])*(temp2[0] - temp1[0]) + (temp2[1] - temp1[1])*(temp2[1] - temp1[1]))+32.0;
  1475.         height = FloatAbs(temp1[2] - temp2[2]);
  1476.     }
  1477.     SetMenuTitle(menu, "Stats-%N", client);
  1478.     if(J_type == JumpType_Ladder)
  1479.     {
  1480.         Format(hint, 255, "%s%s\n [Distance] %.2f\n [Height] %.2f\n [PreStrafe] %.2f\n [Strafe] %d\n [MaxSpeed] %.2f\n%.2f",JumpName[J_type], postfix, width, height, PreStrafe[client], g_Strafe[client], LJ_MaxSpeed[client], LJ_SyncRate[client]);
  1481.         Format(cns, 255, "%s%s Distance : %.2f, Height : %.2f, PreStrafe : %.2f, Strafe : %d, MaxSpeed : %.2f, Sync : %.2f%s",JumpName[J_type], postfix, width, height, PreStrafe[client], g_Strafe[client], LJ_MaxSpeed[client], LJ_SyncRate[client], edge);
  1482.     }
  1483.     else
  1484.     {
  1485.         Format(hint, 255, "%s%s\n [Distance] %.2f\n [PreStrafe] %.2f\n [Strafe] %d\n [MaxSpeed] %.2f\n%.2f",JumpName[J_type], postfix, distance, PreStrafe[client], g_Strafe[client], LJ_MaxSpeed[client], LJ_SyncRate[client]);
  1486.         Format(cns, 1024, "%s%s Distance : %.2f, PreStrafe : %.2f Strafe : %d, MaxSpeed : %.2f, Sync : %.2f%s",JumpName[J_type], postfix, distance, PreStrafe[client], g_Strafe[client], LJ_MaxSpeed[client], LJ_SyncRate[client], edge);
  1487.     }
  1488.    
  1489.     Client_PrintKeyHintText(client, hint);
  1490.     for (new i = 1; i <= MaxClients; i++)
  1491.     {
  1492.         if (IsClientInGame(i))
  1493.         {
  1494.             if(!IsPlayerAlive(i) || IsClientObserver(i))
  1495.             {
  1496.                 new iObserverMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
  1497.                 if(iObserverMode == SPECMODE_FIRSTPERSON || iObserverMode == SPECMODE_3RDPERSON)
  1498.                 {
  1499.                     new target = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
  1500.                    
  1501.                     if(target != client || target == i)
  1502.                         continue;
  1503.                    
  1504.                     if(target <= 0 || target > MaxClients)
  1505.                         continue;
  1506.                    
  1507.                     Client_PrintKeyHintText(i, hint);
  1508.                 }
  1509.                 else
  1510.                 {
  1511.                     continue;
  1512.                 }
  1513.             }
  1514.         }
  1515.     }
  1516.  
  1517.     Format(cns, 1024,"%s\n#Strafe  MaxSpeed  Gains  Loses   Time  Sync",cns);
  1518.     for(new i = 0; i < g_Strafe[client]; i++)
  1519.     {
  1520.         if(i < 12)
  1521.         {
  1522.             Format_Num(i+1, num, 5, true);
  1523.             FormatTime_LJ(LJ_MaxSpeedStrafe[client][i], max, 50, true);
  1524.             FormatTime_LJ(LJ_Gains[client][i], gain, 50, true);
  1525.             FormatTime_LJ(LJ_Lost[client][i], lose, 50, true);
  1526.             FormatTime_LJ(LJ_SyncRateStrafe[client][i], sync, 50, true);
  1527.             FormatTime_LJ(LJ_FrameRate[i], framerate, 50, true);
  1528.             Format(desc, 1024, "%s\n %s %s %s %s %s %s", desc, num, max, gain, lose, framerate, sync);
  1529.         }
  1530.     }
  1531.     for(new i = 0; i < g_Strafe[client]; i++)
  1532.     {
  1533.         if(i < MAXSTR)
  1534.         {
  1535.             Format_Num(i+1, num, 5, false);
  1536.             FormatTime_LJ(LJ_MaxSpeedStrafe[client][i], max, 50, false);
  1537.             FormatTime_LJ(LJ_Gains[client][i], gain, 50, false);
  1538.             FormatTime_LJ(LJ_Lost[client][i], lose, 50, false);
  1539.             FormatTime_LJ(LJ_SyncRateStrafe[client][i], sync, 50, false);
  1540.             FormatTime_LJ(LJ_FrameRate[i], framerate, 50, false);
  1541.             Format(cns, 1024, "%s\n   %s     %s  %s %s %s %s", cns, num, max, gain, lose, framerate, sync);
  1542.         }
  1543.     }
  1544.     if(NoDucking[client])
  1545.     {
  1546.         Format(desc, 1024, "%s\n   %.2f%%  +No Duck", desc, LJ_SyncRate[client]);
  1547.         Format(cns, 1024, "%s\n   +No Duck", cns);
  1548.         NoDucking[client] = false;
  1549.     }
  1550.     else
  1551.         Format(desc, 1024, "%s\n   %.2f%%", desc, LJ_SyncRate[client]);
  1552.     PrintToConsole(client, cns);
  1553.     PrintToConsole(client, "     ");
  1554.     AddMenuItem(menu, "0", desc);
  1555.     SetMenuExitButton(menu, false);
  1556.     if(g_bLJpopup[client])
  1557.     {
  1558.         DisplayMenu(menu, client, MENU_TIME_FOREVER);
  1559.     }
  1560.     for(new g = 1; g <= MaxClients; g++)
  1561.     {
  1562.         if(IsClientInGame(g))
  1563.         {
  1564.             if(IsClientObserver(g))
  1565.             {
  1566.                 new obTarget = GetEntPropEnt(g, Prop_Send, "m_hObserverTarget");
  1567.                 if((obTarget > 0)&&(obTarget==client))
  1568.                 {
  1569.                     DisplayMenu(menu, g, MENU_TIME_FOREVER);
  1570.                    
  1571.                     Client_PrintKeyHintText(g, hint);
  1572.                    
  1573.                     PrintToConsole(g, cns);
  1574.                     PrintToConsole(g, "     ");
  1575.                 }
  1576.             }
  1577.         }
  1578.     }
  1579.     if(fail)
  1580.     {
  1581.         return Plugin_Handled;
  1582.     }
  1583.     if(J_type == JumpType_Wj||J_type == JumpType_WjUp)
  1584.     {
  1585.         if(distance >= g_Print_WJ)
  1586.         {
  1587.             PrintToChatLJ("\x04[\x01%s\x04]\x03%N - \x01%.3f\x04units!",JumpName[J_type],client,distance);
  1588.         }
  1589.     }
  1590.     else if(J_type == JumpType_LongJump)
  1591.     {
  1592.         if(distance >= g_Print_LJ)
  1593.         {
  1594.             PrintToChatLJ("\x04[\x01%s\x04]\x03%N - \x01%.3f\x04units!",JumpName[J_type],client,distance);
  1595.             PlayLJSound(client, distance);
  1596.         }
  1597.     }
  1598.     else if(J_type == JumpType_BlockLongJump)
  1599.     {
  1600.         if(blockdistance >= g_Print_Block_LJ)
  1601.         {
  1602.             PrintToChatLJ("\x04[\x01%s\x04]\x03%N - \x01%.0f\x04units!\n (actual : %.3f, Edge : %.3f)",JumpName[J_type],client,blockdistance, distance, g_EdgeDist[client]);
  1603.             PlayLJSound(client, distance);
  1604.         }
  1605.     }
  1606.     else if(J_type == JumpType_BlockBhopJump)
  1607.     {
  1608.         if(blockdistance >= g_Print_Block_BJ)
  1609.         {
  1610.             PrintToChatLJ("\x04[\x01%s\x04]\x03%N - \x01%.0f\x04units!\n (actual : %.3f, Edge : %.3f)",JumpName[J_type],client,blockdistance, distance, g_EdgeDist[client]);
  1611.         }
  1612.     }
  1613.     else if(J_type == JumpType_BhopJump||J_type == JumpType_BhopUpJump)
  1614.     {
  1615.         if(distance >= g_Print_BJ)
  1616.         {
  1617.             PrintToChatLJ("\x04[\x05%s\x04]\x03%N - \x01%.3f\x04units!",JumpName[J_type],client,distance);
  1618.         }
  1619.     }
  1620.    
  1621.     if(distance >= g_DB_Record)
  1622.     {
  1623.         new mode = Timer_GetMode(client);
  1624.        
  1625.         if(g_Physics[mode][ModeLJStats])
  1626.         {
  1627.             if(IsValidType(J_type))
  1628.             {
  1629.                 RecordQuery(client, J_type, distance, PreStrafe[client], g_Strafe[client]);
  1630.             }
  1631.             if(IsBlockJumpType(J_type))
  1632.             {
  1633.                 if(J_type == JumpType_BlockLongJump)
  1634.                 {
  1635.                     RecordQuery(client, JumpType_LongJump, distance, PreStrafe[client], g_Strafe[client]);
  1636.                     RecordQuery(client, J_type, blockdistance, PreStrafe[client], g_Strafe[client]);
  1637.                 }
  1638.                 else if(J_type == JumpType_BlockBhopJump)
  1639.                 {
  1640.                     RecordQuery(client, JumpType_BhopJump, distance, PreStrafe[client], g_Strafe[client]);
  1641.                     RecordQuery(client, J_type, blockdistance, PreStrafe[client], g_Strafe[client]);
  1642.                 }
  1643.             }
  1644.         }
  1645.     }
  1646.    
  1647.     return Plugin_Continue;
  1648. }
  1649. public emptyhandler(Handle:menu, MenuAction:action, client, select)
  1650. {
  1651.     if(action == MenuAction_Select)
  1652.     {
  1653.  
  1654.     }
  1655.     else if(action == MenuAction_Cancel)
  1656.     {
  1657.         if(select == MenuCancel_ExitBack)
  1658.         {
  1659.  
  1660.         }
  1661.         else if(select == MenuCancel_Exit)
  1662.         {
  1663.         }
  1664.     }
  1665.     else if(action == MenuAction_End)
  1666.     {
  1667.     }
  1668. }
  1669. stock Format_Num(const num, String:txt[], iSize, bool:popup)
  1670. {
  1671.     if(popup)
  1672.     {
  1673.         if(num<10)
  1674.             Format(txt, iSize, "  %d",num);
  1675.         else
  1676.             Format(txt, iSize, "%d", num);
  1677.     }
  1678.     else
  1679.     {
  1680.         if(num<10)
  1681.             Format(txt, iSize, " %d",num);
  1682.         else
  1683.             Format(txt, iSize, "%d", num);
  1684.     }
  1685. }
  1686. stock FormatTime_LJ(const Float:time, String:txt[], iSize, bool:popup)
  1687. {
  1688.     if(popup)
  1689.     {
  1690.         if(time >= 100.0)
  1691.             Format(txt, iSize, "%.2f", time);
  1692.         else if(10.0 < time < 100.0)
  1693.             Format(txt, iSize, " %.2f ", time);
  1694.         else if(time < 10.0)
  1695.             Format(txt, iSize, "  %.2f  ", time);
  1696.     }
  1697.     else
  1698.     {
  1699.         if(time >= 100.0)
  1700.             Format(txt, iSize, "%.2f", time);
  1701.         else if(10.0 < time < 100.0)
  1702.             Format(txt, iSize, " %.2f", time);
  1703.         else if(time < 10.0)
  1704.             Format(txt, iSize, "  %.2f", time);
  1705.     }
  1706. }
  1707. stock PrintToChatLJ(const String:msg[], any:...)
  1708. {
  1709.     decl String:buffer[512];
  1710.     for(new i = 1; i <= MaxClients; i++)
  1711.     {
  1712.         if(IsClientInGame(i))
  1713.         {
  1714.             if(g_ShowMsg == 0)
  1715.             {
  1716.                 SetGlobalTransTarget(i);
  1717.                 VFormat(buffer, sizeof(buffer), msg, 2);
  1718.                 PrintToChat(i, buffer);
  1719.             }
  1720.             else
  1721.             {
  1722.                 if(g_bLJmode[i])
  1723.                 {
  1724.                     SetGlobalTransTarget(i);
  1725.                     VFormat(buffer, sizeof(buffer), msg, 2);
  1726.                     PrintToChat(i, buffer);
  1727.                 }
  1728.             }
  1729.         }
  1730.     }
  1731. }
  1732. PlayLJSound(client, Float:distance)
  1733. {
  1734.     new playsound = -1;
  1735.     if(distance < g_Sound[0])
  1736.         return;
  1737.     if(g_Sound[0] <= distance < g_Sound[1])
  1738.         playsound = 0;
  1739.     else if(distance < g_Sound[2])
  1740.         playsound = 1;
  1741.     else if(distance < g_Sound[3])
  1742.         playsound = 2;
  1743.     else if(distance < g_Sound[4])
  1744.         playsound = 3;
  1745.     else if(g_Sound[4] <= distance)
  1746.         playsound = 4;
  1747.     if(playsound != -1)
  1748.     {
  1749.         if(g_bLJplaysnd[client])
  1750.         {
  1751.             EmitSoundToClient(client, LJ_SOUND[playsound]);
  1752.         }
  1753.     }
  1754. }
  1755. /*********************************
  1756. *******************QUERY*********/
  1757. ConnectToDB()
  1758. {
  1759.     decl String:dbname[128];
  1760.     GetConVarString(g_hCvar_DB, dbname, sizeof(dbname));
  1761.     if(strlen(dbname) > 0)
  1762.     {
  1763.         SQL_TConnect(getmaindb, dbname);
  1764.     }
  1765. }
  1766. public getmaindb(Handle:owner, Handle:dbhandle, const String:error[], any:data)
  1767. {//check current connection. and data tables
  1768.     if(dbhandle == INVALID_HANDLE)
  1769.     {
  1770.         PrintToChatAll("Ljstats DB connection Failed : %s", error);
  1771.     }
  1772.     else
  1773.     {
  1774.         maindb = dbhandle;
  1775.         SQL_TQuery(maindb, empty_query, "create table if not exists `ljstats` (`id` INTEGER PRIMARY KEY, `steamid` varchar(64) NOT NULL,`name` varchar(64) NOT NULL, `type` int(11) NOT NULL, `distance` float NOT NULL,`pre` float NOT NULL,`strafe` int(11) NOT NULL);", DBPrio_High);
  1776.     }
  1777. }
  1778. public empty_query(Handle:owner, Handle:hndl, const String:error[], any:client)
  1779. {
  1780.     if(hndl == INVALID_HANDLE)
  1781.     {
  1782.         PrintToChatAll("error %s", error);
  1783.     }
  1784. }
  1785.  
  1786. RecordQuery(client, JumpType:type, Float:distance, Float:pre, strafe)
  1787. {
  1788.     if(maindb != INVALID_HANDLE)
  1789.     {
  1790.         decl String:query[512], String:steamid[64], String:temp[64], String:name[64];
  1791.         GetClientName(client, temp, sizeof(temp));
  1792.         SQL_EscapeString(maindb, temp, name, sizeof(name));
  1793.         GetClientAuthString(client, steamid, sizeof(steamid));
  1794.         Format(query, sizeof(query), "select distance from 'ljstats' where steamid = '%s' and type = %d", steamid, type);
  1795.         new Handle:datapack = CreateDataPack();
  1796.         WritePackString(datapack, steamid);
  1797.         WritePackString(datapack, name);
  1798.         WritePackCell(datapack, _:type);
  1799.         WritePackFloat(datapack, distance);
  1800.         WritePackFloat(datapack, pre);
  1801.         WritePackCell(datapack, strafe);
  1802.         SQL_TQuery(maindb, SelectRecord, query, datapack);
  1803.     }
  1804. }
  1805.  
  1806. public SelectRecord(Handle:owner, Handle:hndl, const String:error[], any:datapack)
  1807. {
  1808.     ResetPack(datapack);
  1809.     decl String:steamid[64], String:name[64];
  1810.     ReadPackString(datapack, steamid, sizeof(steamid));
  1811.     ReadPackString(datapack, name, sizeof(name));
  1812.     new type = ReadPackCell(datapack);
  1813.     new Float:distance = ReadPackFloat(datapack);
  1814.     new Float:pre = ReadPackFloat(datapack);
  1815.     new strafe = ReadPackCell(datapack);
  1816.     CloseHandle(datapack);
  1817.     if(hndl == INVALID_HANDLE)
  1818.     {
  1819.         LogError("error %s", error);
  1820.     }
  1821.     else
  1822.     {
  1823.         new DBResult:result;
  1824.         decl String:query[512];
  1825.         if(SQL_GetRowCount(hndl) != 0)
  1826.         {
  1827.             while(SQL_FetchRow(hndl))
  1828.             {
  1829.                 new Float:temp = SQL_FetchFloat(hndl, 0, result);
  1830.                 if(distance > temp)
  1831.                 {
  1832.                     Format(query, sizeof(query), "update 'ljstats' set name = '%s', distance = %f, pre = %f, strafe = %d where steamid = '%s' and type = %d", name, distance, pre, strafe, steamid, type);
  1833.                     SQL_TQuery(maindb, empty_query, query, 0);
  1834.                 }
  1835.             }
  1836.         }
  1837.         else
  1838.         {
  1839.             Format(query, sizeof(query), "insert into 'ljstats' (steamid, name, type, distance, pre, strafe) values('%s', '%s', %d, %f, %f, %d)", steamid, name, type, distance, pre, strafe);
  1840.             SQL_TQuery(maindb, empty_query, query, 0);
  1841.         }
  1842.     }
  1843. }
  1844. public Action:Command_ljadm(client, args)
  1845. {
  1846.     if(client != 0)
  1847.     {
  1848.         AdmTopMenu(client);
  1849.     }
  1850.     return Plugin_Handled;
  1851. }
  1852.  
  1853. public Action:Command_ljtop(client, args)
  1854. {
  1855.     if(client != 0)
  1856.     {
  1857.         TopMenu(client);
  1858.     }
  1859.     return Plugin_Handled;
  1860. }
  1861.  
  1862. TopMenu(client)
  1863. {
  1864.     if(h_TopMenu!=INVALID_HANDLE)
  1865.     {
  1866.         DisplayMenu(h_TopMenu, client, MENU_TIME_FOREVER);
  1867.     }
  1868. }
  1869.  
  1870. LJBlockMenu(client)
  1871. {
  1872.     if(h_LJBlockMenu != INVALID_HANDLE)
  1873.     {
  1874.         DisplayMenu(h_LJBlockMenu, client, MENU_TIME_FOREVER);
  1875.     }
  1876. }
  1877.  
  1878. CreateTopMenu()
  1879. {
  1880.     h_TopMenu = CreateMenu(TopListHandler);
  1881.     SetMenuTitle(h_TopMenu, "LongJump Stats Top\n Bug Report : jsbhop@gmail.com\n Weird jump records will be reset soon.");
  1882.     decl String:info[10];
  1883.     for(new JumpType:i = JumpType_None ; i < JumpType; i++)
  1884.     {
  1885.         if(IsDBType(i))
  1886.         {
  1887.             Format(info, sizeof(info), "%d", i);
  1888.             AddMenuItem(h_TopMenu, info, JumpName[i]);
  1889.         }
  1890.     }
  1891.     h_LJBlockMenu = CreateMenu(LJBlockHandler);
  1892.     SetMenuTitle(h_LJBlockMenu, "Block Jump Menu");
  1893.     AddMenuItem(h_LJBlockMenu, "0", "Select Destination");
  1894.     AddMenuItem(h_LJBlockMenu, "0", "Reset Destination");
  1895. }
  1896. AdmTopMenu(client)
  1897. {
  1898.     new Handle:menu = CreateMenu(AdmTopMenu_Handler);
  1899.     SetMenuTitle(menu, "Select JumpType of record to fix");
  1900.     decl String:info[10];
  1901.     for(new JumpType:i = JumpType_None ; i < JumpType; i++)
  1902.     {
  1903.         if(IsDBType(i))
  1904.         {
  1905.             Format(info, sizeof(info), "%d", i);
  1906.             AddMenuItem(menu, info, JumpName[i]);
  1907.         }
  1908.     }
  1909.     DisplayMenu(menu, client, MENU_TIME_FOREVER);
  1910. }
  1911. public AdmTopMenu_Handler(Handle:menu, MenuAction:action, client, select)
  1912. {
  1913.     if(action == MenuAction_Select)
  1914.     {
  1915.         decl String:info[10];
  1916.         GetMenuItem(menu, select, info, sizeof(info));
  1917.         Query_GetTop(client, JumpType:StringToInt(info), true);
  1918.     }
  1919.     else if(action == MenuAction_Cancel)
  1920.     {
  1921.         if(select == MenuCancel_Exit)
  1922.         {
  1923.         }
  1924.     }
  1925.     else if(action == MenuAction_End)
  1926.     {
  1927.     }
  1928. }
  1929. public TopListHandler(Handle:menu, MenuAction:action, client, select)
  1930. {
  1931.     if(action == MenuAction_Select)
  1932.     {
  1933.         decl String:info[10];
  1934.         GetMenuItem(menu, select, info, sizeof(info));
  1935.         Query_GetTop(client, JumpType:StringToInt(info), false);
  1936.     }
  1937.     else if(action == MenuAction_Cancel)
  1938.     {
  1939.         if(select == MenuCancel_Exit)
  1940.         {
  1941.         }
  1942.     }
  1943.     else if(action == MenuAction_End)
  1944.     {
  1945.     }
  1946. }
  1947. Query_GetTop(client, JumpType:type, bool:adm)
  1948. {
  1949.     if(maindb != INVALID_HANDLE)
  1950.     {
  1951.         new userid = GetClientUserId(client);
  1952.         decl String:query[512];
  1953.         new Handle:datapack = CreateDataPack();
  1954.         WritePackCell(datapack, userid);
  1955.         WritePackCell(datapack, _:type);
  1956.         Format(query, sizeof(query), "select id, name, distance, pre, strafe from 'ljstats' where type = %d order by distance desc limit 10", type);
  1957.         if(!adm)
  1958.         {          
  1959.             SQL_TQuery(maindb, query_toplist_menu, query, datapack);
  1960.         }
  1961.         else
  1962.         {
  1963.             SQL_TQuery(maindb, query_toplist_menu_adm, query, datapack);
  1964.         }
  1965.     }
  1966. }
  1967. public query_toplist_menu(Handle:owner, Handle:hndl, const String:error[], any:datapack)
  1968. {
  1969.     ResetPack(datapack);
  1970.     new userid = ReadPackCell(datapack);
  1971.     new JumpType:type = JumpType:ReadPackCell(datapack);
  1972.     CloseHandle(datapack);
  1973.     new client = GetClientOfUserId(userid);
  1974.     if (hndl == INVALID_HANDLE)
  1975.     {
  1976.         LogError("toplist_menu %s", error);
  1977.     }
  1978.     else
  1979.     {
  1980.         new Handle:panel = CreatePanel(INVALID_HANDLE);
  1981.         decl String:text[256], String:name[64], Float:distance, Float:pre, strafe, DBResult:result;
  1982.         Format(text, sizeof(text), "LongJump Stats Top - %s", JumpName[type]);
  1983.         SetPanelTitle(panel, text);
  1984.         if(SQL_GetRowCount(hndl) != 0)
  1985.         {
  1986.             new count;
  1987.             while(SQL_FetchRow(hndl))
  1988.             {
  1989.                 SQL_FetchString(hndl, 1, name, sizeof(name), result);
  1990.                 distance = SQL_FetchFloat(hndl, 2, result);
  1991.                 pre = SQL_FetchFloat(hndl, 3, result);
  1992.                 strafe = SQL_FetchInt(hndl, 4, result);
  1993.                 Format(text, sizeof(text), "%s - %.3f (%.2f, %d stf)", name, distance, pre, strafe);
  1994.                 DrawPanelItem(panel, text);
  1995.                 count++;
  1996.             }
  1997.         }
  1998.         else
  1999.         {
  2000.             DrawPanelText(panel, "     No Records     ");
  2001.         }
  2002.         DrawPanelText(panel, "<9>. Go Back");
  2003.         DrawPanelText(panel, "<0>. Exit");
  2004.         SetPanelKeys(panel, (1<<8)|(1<<9));
  2005.         SendPanelToClient(panel, client, toplist_handler, MENU_TIME_FOREVER);
  2006.         CloseHandle(panel);
  2007.     }
  2008. }
  2009. public toplist_handler(Handle:menu, MenuAction:action, client, select)
  2010. {
  2011.     if (action == MenuAction_Select)
  2012.     {
  2013.         if(select == 9)
  2014.         {
  2015.             TopMenu(client);
  2016.         }
  2017.     }
  2018.     else if (action == MenuAction_Cancel)
  2019.     {
  2020.     }
  2021. }
  2022. public query_toplist_menu_adm(Handle:owner, Handle:hndl, const String:error[], any:datapack)
  2023. {
  2024.     ResetPack(datapack);
  2025.     new userid = ReadPackCell(datapack);
  2026.     new JumpType:type = JumpType:ReadPackCell(datapack);
  2027.     CloseHandle(datapack);
  2028.     new client = GetClientOfUserId(userid);
  2029.     if (hndl == INVALID_HANDLE)
  2030.     {
  2031.         LogError("toplist_menu %s", error);
  2032.     }
  2033.     else
  2034.     {
  2035.         new Handle:menu = CreateMenu(AdmMenu_Handler);
  2036.         decl String:text[256], String:info[20], String:name[64], Float:distance, DBResult:result, id;
  2037.         Format(text, sizeof(text), "Select To Delete - %s", JumpName[type]);
  2038.         SetMenuTitle(menu, text);
  2039.         if(SQL_GetRowCount(hndl) != 0)
  2040.         {
  2041.             while(SQL_FetchRow(hndl))
  2042.             {
  2043.                 id = SQL_FetchInt(hndl, 0, result);
  2044.                 SQL_FetchString(hndl, 1, name, sizeof(name), result);
  2045.                 distance = SQL_FetchFloat(hndl, 2, result);
  2046.                 Format(info, sizeof(info), "%d", id);
  2047.                 Format(text, sizeof(text), "%s - %.2f Units", name, distance);
  2048.                 AddMenuItem(menu, info, text);
  2049.             }
  2050.         }
  2051.         else
  2052.         {
  2053.             AddMenuItem(menu, info, "no record", ITEMDRAW_DISABLED);
  2054.         }
  2055.         SetMenuExitBackButton(menu, true);
  2056.         DisplayMenu(menu, client, MENU_TIME_FOREVER);
  2057.     }
  2058. }
  2059. public AdmMenu_Handler(Handle:menu, MenuAction:action, client, select)
  2060. {
  2061.     if (action == MenuAction_Select)
  2062.     {
  2063.         decl String:info[10], String:query[512];
  2064.         GetMenuItem(menu, select, info, sizeof(info));
  2065.         Format(query, sizeof(query), "delete from 'ljstats' where id = %d", StringToInt(info));
  2066.         SQL_TQuery(maindb, empty_query, query, 0);
  2067.         RemoveMenuItem(menu, select);
  2068.         DisplayMenuAtItem(menu, client, GetMenuSelectionPosition(), MENU_TIME_FOREVER);
  2069.     }
  2070.     else if (action == MenuAction_Cancel)
  2071.     {
  2072.         if(select == MenuCancel_ExitBack)
  2073.         {
  2074.             AdmTopMenu(client);
  2075.         }
  2076.     }
  2077. }
  2078. bool:IsDBType(JumpType:type)
  2079. {
  2080.     if(IsValidType(type)||IsBlockJumpType(type))
  2081.     {
  2082.         return true;
  2083.     }
  2084.     return false;
  2085. }
  2086. bool:IsValidType(JumpType:type)
  2087. {
  2088.     if(type == JumpType_LongJump || type == JumpType_BhopJump || type == JumpType_Wj)
  2089.     {
  2090.         return true;
  2091.     }
  2092.     return false;
  2093. }
  2094.  
  2095. bool:IsBlockJumpType(JumpType:type)
  2096. {
  2097.     if(type == JumpType_BlockLongJump || type == JumpType_BlockBhopJump)
  2098.         return true;
  2099.     return false;
  2100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement