--- climb.sma 2007/11/18 13:22:37 22 +++ climb.sma 2008/02/24 09:34:01 40 @@ -2,17 +2,18 @@ Climb v2.0a4 Copyright (C) 2006-2007 Ian (Juan) Cammarata -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. -You should have received a copy of the GNU General Public License along with -this program; go to http://www.opensource.org/licenses/gpl-license.php +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . -------------------------------------------------------------------------------- http://ian.cammarata.us @@ -127,7 +128,6 @@ +: Cvars mp_autoteambalance and mp_limitteams are set to 0 when a start button is found, and reverted when the map changes. +: Support for a2 maps start/finish buttons. +: Commands measure and measure2. -+: Multiplayer friendly bhops. +: Command 'weapons', gives client one of each speed weapon. +: Ranking by weapon speed. ex: If you beat a map with AWP, you'll be ranked above other weapon scores. +: Command countdown to have time countdown from your best time instead of counting up. @@ -135,7 +135,8 @@ -: Plugin ad on client connect. -: WebMod support since it is a huge security vulnerability. -: Cvars: climb_webmod, climb_stats_path, climb_stats_url, ip_internal, ip_external -c: Tweaked semiclip to hopefully eliminate lag problems reported by some people. +//c: Tweaked semiclip to hopefully eliminate lag problems reported by some people. +//c: New semiclip, should be flawless now. c: Cvar climb_water_nodraw changes take effect without reloading map. c: Database now stores multiple records per map per player. c: Cvar climb_db_pass is now protected. @@ -268,8 +269,9 @@ #include #include -new const VERSION[ ] = "a3.7.1 Nov 18 06:22 MST" +new const VERSION[ ] = "a3.7.7 Feb 23 18:32 MST" new const TRKCVAR[ ] = "climb_version" + new const DONOTHING[ ] = "donothing" new const NULLSTR[ ] = "" @@ -298,10 +300,10 @@ #define ORIGINS_SIZE 48 new Float:origins[33][ORIGINS_SIZE] #define ORIG_UNGC 40 -#define ORIG_PAUS 44 -//#define ORIG_X 0 -//#define ORIG_Y 1 -//#define ORIG_Z 2 +#define ORIG_PAUSX 44 +#define ORIG_PAUSY 45 +#define ORIG_PAUSZ 46 +#define ORIG_PAUSG 47 #define ORIG_GRAV 3 new time_stamps[33][5]//time_stamps[id][x] @@ -311,24 +313,23 @@ #define TS_CPGC 3 //This one holds a flag, not a timestamp so it can be < 1 second #define TS_KNIFE 4 -#define TIMER_SIZE 16 +#define TIMER_SIZE 15 new timer[33][TIMER_SIZE]//timer[id][x]: #define TMR_CFLAGS 0 //Status -#define TMR_STARTD 1 //Start Time -#define TMR_FINISH 2 //Finish Time -#define TMR_CNTCPS 3 //CP Count -#define TMR_CNTGCS 4 //GC Count -#define TMR_CNTBST 5 //Boosts -#define TMR_BSTTME 6 //Best Time -#define TMR_BSTCPS 7 //Best CP -#define TMR_BSTGCS 8 //Best GC -#define TMR_BSTBST 9 //Number of boosts used -#define TMR_SESFIN 10 //Finished this session -#define TMR_MAPFIN 11 //Total times finished this map -#define TMR_DBUSER 12 //Database player ID; 0=not registered; -1=not registered & shared steam id -#define TMR_CPPOS 13 //Current CP offset, for cycling back and forward through cps -#define TMR_CNTWPN 14 //Current weapon rank modifier -#define TMR_BSTWPN 15 //Best score weapon rank modifier +#define TMR_CNTTME 1 //Time / in deciseconds +#define TMR_CNTCPS 2 //CP Count +#define TMR_CNTGCS 3 //GC Count +#define TMR_CNTBST 4 //Boosts +#define TMR_BSTTME 5 //Best Time / in deciseconds +#define TMR_BSTCPS 6 //Best CP +#define TMR_BSTGCS 7 //Best GC +#define TMR_BSTBST 8 //Number of boosts used +#define TMR_SESFIN 9 //Finished this session +#define TMR_MAPFIN 10 //Total times finished this map +#define TMR_DBUSER 11 //Database player ID; 0=not registered; -1=not registered & shared steam id +#define TMR_CPPOS 12 //Current CP offset, for cycling back and forward through cps +#define TMR_CNTWPN 13 //Current weapon rank modifier +#define TMR_BSTWPN 14 //Best score weapon rank modifier //Temp save vars new savepos = 0, steamid[32][32], Float:originssave[32][ORIGINS_SIZE], timersave[32][TIMER_SIZE] @@ -343,16 +344,10 @@ new ST_BTNS[9], FN_BTNS[9], ST_BTN_CNT = 0, FN_BTN_CNT = 0 new dyn_spawn_ids[32], dyn_spawn_count, Float:spawn_tp_orig[3], Float:start_tp_orig[3] -new bool:sclip[33],Float:post_think_vel[33][3],sc_fcount +new Float:post_think_vel[33][3] new LIMIT_TEAMS_OLD, TEAM_BALANCE_OLD -//Bhop fix vars -#define MAX_DOORS 500 -new door_count = 0, func_doors[MAX_DOORS][3], Float:door_tp_pos[MAX_DOORS][3] -new bhop_failid[33], bool:bhop_fail[33] -//func_doors[x]{ id, speed, angles } - //Cvar Pointers new p_climb, p_auto, p_boost, p_cpprice, p_startmoney new p_msg_r, p_msg_g, p_msg_b, p_msg_x, p_msg_y @@ -371,9 +366,7 @@ #define TSK_AUTORSPN 100 //100+: Auto Respawn //#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer #define TSK_FLIGHT 200 -#define TSK_BHOP 250 -#define TSK_CLEAR_FAIL 300 -#define TSK_MEASURE2 350 +#define TSK_MEASURE2 250 //Status timer[id][TMR_CFLAGS]&=x #define CF_NULL 0 //Passed to change_boost() to remove all boost flags @@ -392,7 +385,14 @@ #define CF_COUNTDOWN (1<<11) #define CF_SUNGLASSES (1<<12) -new SVC_STATUSICON, SVC_TEAMINFO, SVC_ROUNDTIME, SVC_FLASHLIGHT, SVC_SCREENFADE +#define SILENT 1 + +//Boost Flags for climb_boost CVAR +#define SOLID 1 +#define DJUMP 2 +#define SJUMP 4 + +new SVC_STATUSICON, SVC_TEAMINFO, SVC_ROUNDTIME, SVC_FLASHLIGHT, SVC_SCREENFADE, SVC_CLCORPSE; new SCORES_PATH[100], HSCORES_PATH[100] @@ -407,7 +407,7 @@ p_climb = register_cvar( "climb", "0", FCVAR_SERVER ) p_auto = register_cvar( "climb_auto", "1" ) - p_boost = register_cvar( "climb_boost", "1" ) + p_boost = register_cvar( "climb_boost", "7" ) p_cpprice = register_cvar( "climb_cpprice", "0" ) p_startmoney = register_cvar( "climb_startmoney", "1337" ) @@ -421,57 +421,58 @@ register_cvar( "climb_db_serverid", NULLSTR ) register_cvar( "climb_db_exists", "0" ) - p_msg_r = register_cvar( "climb_msg_r", "0" ) - p_msg_g = register_cvar( "climb_msg_g", "150" ) - p_msg_b = register_cvar( "climb_msg_b", "250" ) - p_msg_x = register_cvar( "climb_msg_x", "0.05" ) - p_msg_y = register_cvar( "climb_msg_y", "0.5" ) - - p_light_r = register_cvar( "climb_light_r", "255" ) - p_light_g = register_cvar( "climb_light_g", "255" ) - p_light_b = register_cvar( "climb_light_b", "255" ) - - p_sounds = register_cvar( "climb_sounds", "1" ) - p_render = register_cvar( "climb_unsolid_type", "0" ) - p_start_respawn = register_cvar( "climb_start_respawn", "0" ) - p_water_nodraw = register_cvar( "climb_water_nodraw", "0" ) - - p_stats_hsurl = register_cvar( "climb_stats_hsurl", NULLSTR ) //Use %s in place of map name - p_stats_msg = register_cvar( "climb_stats_msg", NULLSTR ) - - p_allow_spectators = get_cvar_pointer( "allow_spectators" ) - p_teambalance = get_cvar_pointer( "mp_autoteambalance" ) - p_limitteams = get_cvar_pointer( "mp_limitteams" ) + p_msg_r = register_cvar( "climb_msg_r", "0" ); + p_msg_g = register_cvar( "climb_msg_g", "150" ); + p_msg_b = register_cvar( "climb_msg_b", "250" ); + p_msg_x = register_cvar( "climb_msg_x", "0.05" ); + p_msg_y = register_cvar( "climb_msg_y", "0.5" ); + + p_light_r = register_cvar( "climb_light_r", "255" ); + p_light_g = register_cvar( "climb_light_g", "255" ); + p_light_b = register_cvar( "climb_light_b", "255" ); + + p_sounds = register_cvar( "climb_sounds", "1" ); + p_render = register_cvar( "climb_unsolid_type", "0" ); + p_start_respawn = register_cvar( "climb_start_respawn", "0" ); + p_water_nodraw = register_cvar( "climb_water_nodraw", "0" ); + + p_stats_hsurl = register_cvar( "climb_stats_hsurl", NULLSTR ); //Use %s in place of map name + p_stats_msg = register_cvar( "climb_stats_msg", NULLSTR ); + + p_allow_spectators = get_cvar_pointer( "allow_spectators" ); + p_teambalance = get_cvar_pointer( "mp_autoteambalance" ); + p_limitteams = get_cvar_pointer( "mp_limitteams" ); - MAXPLAYERS = get_maxplayers( ) + MAXPLAYERS = get_maxplayers( ); - TEAM_BALANCE_OLD = get_pcvar_num( p_teambalance ) - LIMIT_TEAMS_OLD = get_pcvar_num( p_limitteams ) + TEAM_BALANCE_OLD = get_pcvar_num( p_teambalance ); + LIMIT_TEAMS_OLD = get_pcvar_num( p_limitteams ); //Message Pseudo-Constants - SVC_STATUSICON = get_user_msgid( "StatusIcon" ) - SVC_TEAMINFO = get_user_msgid( "TeamInfo" ) - SVC_ROUNDTIME = get_user_msgid( "RoundTime" ) - SVC_FLASHLIGHT = get_user_msgid( "Flashlight" ) - SVC_SCREENFADE = get_user_msgid( "ScreenFade" ) + SVC_STATUSICON = get_user_msgid( "StatusIcon" ); + SVC_TEAMINFO = get_user_msgid( "TeamInfo" ); + SVC_ROUNDTIME = get_user_msgid( "RoundTime" ); + SVC_FLASHLIGHT = get_user_msgid( "Flashlight" ); + SVC_SCREENFADE = get_user_msgid( "ScreenFade" ); + SVC_CLCORPSE = get_user_msgid( "ClCorpse" ); //These commands get blocked always. - register_clcmd( "fullupdate", "block_cmd2" ) + register_clcmd( "fullupdate", "block_cmd2" ); //These commands get blocked when climb is enabled. - register_clcmd( "chooseteam", "spectate" ) - register_clcmd( "buy", "block_cmd" ) - register_clcmd( "buyammo1", "block_cmd" ) - register_clcmd( "buyammo2", "block_cmd" ) - register_clcmd( "buyequip", "block_cmd" ) + register_clcmd( "chooseteam", "spectate" ); + register_clcmd( "buy", "block_cmd" ); + register_clcmd( "buyammo1", "block_cmd" ); + register_clcmd( "buyammo2", "block_cmd" ); + register_clcmd( "buyequip", "block_cmd" ); - register_clcmd( "jointeam", "block_jointeam" ) + register_clcmd( "jointeam", "block_jointeam" ); //Commands to detect cheats. - register_clcmd( "+hook", "phook" ) - register_clcmd( "+rope", "phook" ) - register_clcmd( "-hook", "mhook" ) - register_clcmd( "-rope", "mhook" ) + register_clcmd( "+hook", "phook" ); + register_clcmd( "+rope", "phook" ); + register_clcmd( "-hook", "mhook" ); + register_clcmd( "-rope", "mhook" ); //Commands referencing function 'donothing' are picked up by the more flexible code in the client_command forward. register_clcmd( "say help", "help_msg" ) @@ -525,6 +526,7 @@ set_task( 0.5, "hudtime", _, _, _, "b" ) //Task to update time on clients HUD; Task set for half second to minimize flickering of the timer. set_task( 1.0, "spec_update", _, _, _, "b" ) //Task to update spectator array set_task( 5.0, "run_tasks", _, _, _, "b" ) + set_task( 0.1, "timer_tick", _, _, _, "b" ) register_message( get_user_msgid( "CurWeapon" ), "CurWeapon" ) @@ -547,7 +549,7 @@ if( file_exists( ini ) ) { new line = 0, text[50], len - while( read_file( ini, line++, text, sizeof(text)-1 , len ) ) + while( read_file( ini, line++, text, 49 , len ) ) { if( !equal( text, ";", 1 ) && !equal( text, "#", 1 ) && !equal( text, "//", 2 ) ) { @@ -578,32 +580,6 @@ } } } - - static last_ent - new class[31], key[31], val[31] - copy_keyvalue( class, 30, key, 30, val, 30 ) - - if( ent != last_ent && func_doors[door_count][0] && door_count < MAX_DOORS ) - door_count++ - - if( equal( class, "func_door" ) ) - { - //func_doors[x]{ id, speed, angles } - - if( ent != last_ent ) func_doors[door_count][0] = ent - - if( equal( key, "speed" ) ) - func_doors[door_count][1] = str_to_num(val) - if( equal( key, "dmg" ) ) - func_doors[door_count][0] = 0 - if( equal( key, "angles" ) ) - { - new angles[5] - parse( val, angles, 4 ) - func_doors[door_count][2] = str_to_num( angles ) - } - last_ent = ent - } return PLUGIN_CONTINUE } @@ -612,83 +588,6 @@ { new ent, ent2, tmpstr[33], Float:tmpflt - if( func_doors[door_count][0] && door_count < MAX_DOORS ) - door_count++ - - //Find tp spots for doors, in case they're used for bhop - //func_doors[x]{ id, speed, angles } - for( new i = 0; i < door_count; i++ ) - { - ent = func_doors[i][0] - if( !is_valid_ent( ent ) ) func_doors[i][0] = 0 - else - { - new Float:dmins[3], Float:dmaxs[3] - entity_get_vector( ent, EV_VEC_mins, dmins ) - entity_get_vector( ent, EV_VEC_maxs, dmaxs ) - - new dwid = floatround( dmaxs[0] - dmins[0] ) - new dlen = floatround( dmaxs[1] - dmins[1] ) - - //If the door moves up, or is thin, remove it's id from the array - if( func_doors[i][2] < 0 || dwid < 24 || dlen < 24 ) - func_doors[i][0] = 0 - //Otherwise find a safe tp spot in case it's a bhop door - else - { - //If it has a targetname, change the id in array to targeter - entity_get_string( ent, EV_SZ_targetname, tmpstr, 32 ) - if( strlen( tmpstr ) ) - { - ent2 = find_ent_by_target( -1, tmpstr ) - if( ent2 ) - { - func_doors[i][0] = ent2 - - //If targeter is a button, remove it's id from the array - entity_get_string( ent2, EV_SZ_classname, tmpstr, 32 ) - if( equal( tmpstr, "func_button" ) ) - func_doors[i][0] = 0 - } - } - - new Float:tmpvec[3], Float:tmpvec2[3] - - new Float:dr_tc[3] - dr_tc[0] = ( dmaxs[0] + dmins[0] ) / 2 - dr_tc[1] = ( dmaxs[1] + dmins[1] ) / 2 - dr_tc[2] = dmaxs[2] - - tmpvec[0] = ( dmaxs[0] + dmins[0] ) / 2 - tmpvec[1] = dmaxs[1] + 20 - tmpvec[2] = dmaxs[2] + 20 - trace_line( ent, dr_tc, tmpvec, tmpvec2 ) - if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) - door_tp_pos[i] = tmpvec - else - { - tmpvec[1] = dmins[1] - 20 - trace_line( ent, dr_tc, tmpvec, tmpvec2 ) - if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) - door_tp_pos[i] = tmpvec - else - { - tmpvec[0] = dmaxs[0] + 20 - tmpvec[1] = ( dmaxs[1] + dmins[1] ) / 2 - trace_line( ent, dr_tc, tmpvec, tmpvec2 ) - if( !trace_hull( tmpvec, HULL_HUMAN ) && tmpvec2[2] == tmpvec[2] ) - door_tp_pos[i] = tmpvec - else - { - tmpvec[0] = dmins[0] - 20 - door_tp_pos[i] = tmpvec - } - } - } - } - } - } - //Store ent id's for start/fin buttons, some maps change target value after timer starts ent = find_ent_by_class( -1, "func_button" ) while( ent > 0 ) @@ -775,17 +674,6 @@ } } - //If Cvar set, set func_water ents to no draw, helps many peoples FPS - if( get_pcvar_num( p_water_nodraw ) ) - { - ent = find_ent_by_class( -1, "func_water" ) - while( ent > 0 ) - { - set_entity_visibility( ent, 0 ) - ent=find_ent_by_class( ent, "func_water" ) - } - } - //Remove map built in start button sounds ent = find_ent_by_class( -1, "ambient_generic" ) while( ent > 0 ) @@ -1027,7 +915,9 @@ //Do gocheck new cppos = timer[id][TMR_CPPOS] * 4 - for( new i=0; i<3; i++ ) coords[i] = origins[id][cppos + i] + coords[0] = origins[id][cppos] + coords[1] = origins[id][cppos + 1] + coords[2] = origins[id][cppos + 2] entity_set_float( id, EV_FL_gravity, origins[id][3] ) teleport( id, coords ) @@ -1144,16 +1034,14 @@ if( cflags_old & CF_PAUSE ) //unpause { cflags_new += CF_START - timer[id][TMR_STARTD] = get_systime() - timer[id][TMR_STARTD] set_entity_flags( id, FL_FROZEN, 0 ) - unsolid( id ) - entity_set_float( id, EV_FL_gravity, origins[id][ORIG_PAUS + ORIG_GRAV] ) + //set_solid( id, 0 ); + entity_set_float( id, EV_FL_gravity, origins[id][ORIG_PAUSG] ) clmsg( id, "UNPAUSED" ) sfexec( id, 2 ) } else if( cflags_old & CF_START ) //pause { - timer[id][TMR_STARTD] = get_systime() - timer[id][TMR_STARTD] cl_pause( id ) cflags_new += CF_PAUSE } @@ -1172,14 +1060,28 @@ { if( is_climber_alive( id ) ) { - unsolid( id ) + set_solid( id, 0 ); set_rendering( id, kRenderFxGlowShell, 0, 0, 255, kRenderTransColor, 1 ) + //set_pev( id, pev_flags, pev( id, pev_flags ) & FL_FROZEN ) set_entity_flags( id, FL_FROZEN, 1 ) clmsg( id, "PAUSED - say '/unpause' to resume." ) } return PLUGIN_HANDLED } +public timer_tick( ) +{ + new players[32], num, id + get_players( players, num, "ach" ) + + for( new i = 0; i < num; i++ ) + { + id = players[i] + if( timer[id][TMR_CFLAGS] & CF_START ) + timer[id][TMR_CNTTME]++ + } +} + public stop( id ) { if( get_pcvar_num( p_climb ) && timer[id][TMR_CFLAGS] & CF_START ) @@ -1187,8 +1089,7 @@ change_status( id, CF_STOP ) heal(id) //Erase start/finish time stamps, prevents crazy number on scoreboard - timer[id][TMR_STARTD]=0 - timer[id][TMR_FINISH]=0 + timer[id][TMR_CNTTME] = 0 sfexec(id,4) //Execute commands from start/finish config } @@ -1236,7 +1137,9 @@ ) return PLUGIN_CONTINUE //If it's a gun, update pack and clip ammo & silencer - new wpn_id = get_user_weapon( id ) + new wpn_name[17] + get_weaponname( wpn, wpn_name,16 ) + new wpn_id = find_ent_by_owner( -1, wpn_name, id ) if( !wpn_id ) return PLUGIN_CONTINUE new clip = get_msg_arg_int( 3 ) @@ -1380,7 +1283,7 @@ cs_user_spawn( id ) set_pev( id, pev_movetype, MOVETYPE_WALK ) - set_pev( id, pev_solid, SOLID_BBOX ) + set_pev( id, pev_solid, SOLID_SLIDEBOX ) set_pev( id, pev_effects, 0 ) set_pev( id, pev_deadflag, DEAD_NO ) set_pev( id, pev_takedamage, DAMAGE_AIM ) @@ -1397,38 +1300,49 @@ public ResetHUD( id ) {//Spawned - if( get_pcvar_num( p_climb ) ) + if( !get_pcvar_num( p_climb ) ) { - if( !is_user_bot( id ) && !is_user_hltv( id ) ) - { - flight_icons( id )//redraw flashlight hud icons - set_msg_block( SVC_STATUSICON, 2 )//Block buy menu - - if( is_climber_alive( id ) ) - { - //set_pev( id, pev_movetype, MOVETYPE_WALK ) - //cs_set_user_team( id, 2 ) - - heal( id ) - sfexec( id, 1 )//Execute commands from start/finish config - if( get_user_flags( id ) & VIP ) cs_set_user_scoreattrib( id, 4 )//Show admin as VIP on Scoreboard. - - if( timer[id][TMR_CFLAGS] & CF_PAUSE ) - {//If they are paused tp to pause spot and freeze them again. - new Float:coords[3] - for( new i=0; i<3; i++ ) coords[i] = origins[ id - 1 ][ ORIG_PAUS + i ] - teleport( id, coords ) - cl_pause( id ) - } - - //Teleport to cp, start, or primary spawn position - else if( origins[ id - 1 ][ 0 ] || origins[ id - 1][ 1 ] || origins[ id - 1 ][ 2 ]) gocheck( id ) - else if( !teleport( id, start_tp_orig ) ) teleport( id, spawn_tp_orig ) - } + set_msg_block( SVC_STATUSICON, BLOCK_NOT ); + set_msg_block( SVC_CLCORPSE, BLOCK_NOT ); + return; + } + + if( is_user_bot( id ) || is_user_hltv( id ) ) return; + + flight_icons( id ); //redraw flashlight hud icons + set_msg_block( SVC_STATUSICON, BLOCK_SET ); //Block buy menu + set_msg_block( SVC_CLCORPSE, BLOCK_SET ); //block client corpses + + flight_icons( id ); //redraw flashlight hud icons + + if( is_climber_alive( id ) ) + { + heal( id ); + + //Execute commands from start/finish config + sfexec( id, 1 ); + + //Show admin as VIP on Scoreboard. + if( get_user_flags( id ) & VIP ) cs_set_user_scoreattrib( id, 4 ); + + new cppos = timer[id][TMR_CPPOS] * 4; + + //If they are paused tp to pause spot and freeze them again. + if( timer[id][TMR_CFLAGS] & CF_PAUSE ) + { + new Float:coords[3]; + coords[0] = origins[ id ][ ORIG_PAUSX ]; + coords[1] = origins[ id ][ ORIG_PAUSY ]; + coords[2] = origins[ id ][ ORIG_PAUSZ ]; + teleport( id, coords ); + cl_pause( id ); } - sortcssb( ) + //Teleport to cp, start, or primary spawn position + else if( origins[ id ][ cppos ] || origins[ id ][ cppos+1 ] || origins[ id ][ cppos+2 ] ) gocheck( id ); + else teleport( id, start_tp_orig ); + //else if( !teleport( id, start_tp_orig ) ) teleport( id, spawn_tp_orig ); //no need to tp to spawn_tp_orig, they're already there } - else set_msg_block( SVC_STATUSICON, 0 ) + sortcssb( ) } public run_tasks( ) @@ -1439,87 +1353,82 @@ public updatebot( ) { - if(get_pcvar_num(p_climb)) - { - //new players[32], cl - //get_players( players, cl, "ach" ) - new id = find_player( "i" ) - //if(02&&id)server_cmd("kick #%d",get_user_userid(id)) - else if( cl == MAXPLAYERS - 1 && id ) - { - set_entity_visibility( id, 1 ) - server_cmd( "kick #%d", get_user_userid( id ) ) - } - else if( is_user_bot( id ) && id ) - { - set_entity_visibility( id, 0 ) - entity_set_int( id, EV_INT_solid, SOLID_NOT ) - set_pev( id, pev_takedamage, DAMAGE_NO ) - entity_set_vector( id, EV_VEC_origin, Float:{999999,999999,999999} ) - call_think( id ) + if( !get_pcvar_num(p_climb) ) return + + new id = find_player( "i" ) + new cl = get_playersnum( ) + if( cl < MAXPLAYERS - 2 && !id ) + { + //Start borrowed code : from Space Headed's AMXX Bot(bot_api.sma) v0.5.1 + new name[32] + format( name, 31, "Climb v%s", VERSION ) + id = engfunc( EngFunc_CreateFakeClient, name ) + if( pev_valid( id ) ) + { + engfunc( EngFunc_FreeEntPrivateData, id ) + dllfunc( MetaFunc_CallGameEntity, "player", id ) + set_user_info( id, "rate", "3500" ) + set_user_info( id, "cl_updaterate", "25" ) + set_user_info( id, "cl_lw", "1" ) + set_user_info( id, "cl_lc", "1" ) + set_user_info( id, "cl_dlmax", "128" ) + set_user_info( id, "cl_righthand", "1" ) + set_user_info( id, "_vgui_menus", "0" ) + set_user_info( id, "_ah", "0" ) + set_user_info( id, "dm", "0" ) + set_user_info( id, "tracker", "0" ) + set_user_info( id, "friends", "0" ) + set_user_info( id, "*bot", "1" ) + set_pev( id, pev_flags, pev( id, pev_flags ) | FL_FAKECLIENT ) + set_pev( id, pev_colormap, id ) + + new msg[128] + dllfunc( DLLFunc_ClientConnect, id, name, "127.0.0.1", msg ) + dllfunc( DLLFunc_ClientPutInServer, id ) + engfunc( EngFunc_RunPlayerMove, id, Float:{0.0,0.0,0.0}, 0.0, 0.0, 0.0, 0, 0, 76 ) + //End borrowed code + + cs_set_user_team( id, 2 ) + cs_user_spawn( id ) } } + else if( cl == MAXPLAYERS - 1 && id ) + { + set_entity_visibility( id, 1 ) + server_cmd( "kick #%d", get_user_userid( id ) ) + } + else if( id ) + { + set_entity_visibility( id, 0 ) + entity_set_int( id, EV_INT_solid, SOLID_NOT ) + set_pev( id, pev_takedamage, DAMAGE_NO ) + entity_set_vector( id, EV_VEC_origin, Float:{999999,999999,999999} ) + call_think( id ) + } } public check_cvars( ) { - static bool:nodraw + static bool:nodraw; if( get_pcvar_num( p_water_nodraw ) && !nodraw ) { - new ent = find_ent_by_class( -1, "func_water" ) + new ent = find_ent_by_class( -1, "func_water" ); while( ent > 0 ) { - set_entity_visibility( ent, 0 ) - ent = find_ent_by_class( ent, "func_water" ) + set_entity_visibility( ent, 0 ); + ent = find_ent_by_class( ent, "func_water" ); } - nodraw = true + nodraw = true; } else if( !get_pcvar_num( p_water_nodraw ) && nodraw ) { - new ent = find_ent_by_class( -1, "func_water" ) + new ent = find_ent_by_class( -1, "func_water" ); while( ent > 0 ) { - set_entity_visibility( ent, 1 ) - ent = find_ent_by_class( ent, "func_water" ) + set_entity_visibility( ent, 1 ); + ent = find_ent_by_class( ent, "func_water" ); } - nodraw = false + nodraw = false; } } @@ -1547,152 +1456,137 @@ return dif } -public change_boost( id, newboost ) +public boost_enabled( id, boost_type, silent ) +{ + if( get_pcvar_num( p_boost ) & boost_type ) return true; + if( !silent ) clmsg( id, "That boost type has been disabled by the server admin." ); + return false; +} + +stock change_boost( id, newboost, silent = 0 ) {//Change Boost flags - if( !( cvar_enabled( id, p_boost ) && isalive( id ) ) && notpaused( id ) ) return PLUGIN_HANDLED + //if( !( cvar_enabled( id, p_boost, silent ) && isalive( id ) ) && notpaused( id ) ) return; + if( !isalive( id ) || !notpaused( id ) ) return; - new msg[151], rmflag, cflags = timer[ id - 1 ][ TMR_CFLAGS ] + new msg[151], rmflag, cflags = timer[ id ][ TMR_CFLAGS ]; if( cflags & CF_SOLID ) { - if( task_exists( 150 + id ) ) remove_task( 150 + id ) - rmflag = CF_SOLID - msg = "Solid Boost Disabled.^n" + if( task_exists( 150 + id ) ) remove_task( 150 + id ); + rmflag = CF_SOLID; + msg = "Solid Boost Disabled.^n"; } else if( cflags & CF_SUPER_JUMP ) { - rmflag = CF_SUPER_JUMP - msg = "Super Jump Disabled.^n" + rmflag = CF_SUPER_JUMP; + msg = "Super Jump Disabled.^n"; } else if( cflags & CF_DOUBLE_JUMP) { - rmflag = CF_DOUBLE_JUMP - msg = "Double Jump Disabled.^n" + rmflag = CF_DOUBLE_JUMP; + msg = "Double Jump Disabled.^n"; } - if( rmflag > 0 ) timer[ id - 1 ][ TMR_CFLAGS ] -= rmflag - if( !( rmflag & newboost ) && \ - !check_timeout( id, time_stamps[id][TS_BOOST], BOOST_TIMEOUT, ( cflags & CF_START ? get_climber_time( id ) : get_systime() ) ) ) - { - if( newboost == CF_SOLID ) - { - format( msg, 150, "%sSolid Boost Enabled.", msg ) - new ida[1] - ida[0] = id - set_task( 15.0, "solid_boost_timer", 150 + id, ida, 1 ) - if( timer[ id - 1 ][ TMR_CFLAGS ] & CF_START ) timer[ id - 1 ][ TMR_CNTBST ]++ - } - if( newboost == CF_SUPER_JUMP ) format( msg, 150, "%sSuper Jump Enabled.", msg ) - if( newboost == CF_DOUBLE_JUMP ) format( msg, 150, "%sDouble Jump Enabled.", msg ) - timer[ id - 1 ][ TMR_CFLAGS ] |= newboost + if( rmflag > 0 ) timer[ id ][ TMR_CFLAGS ] -= rmflag; + if( !( rmflag & newboost ) && + !check_timeout( id, time_stamps[id][TS_BOOST], BOOST_TIMEOUT, ( cflags & CF_START ? timer[id][TMR_CNTTME] / 10 : get_systime() ) ) ) + { + if( newboost == CF_SOLID && boost_enabled( id, SOLID, silent ) ) + { + format( msg, 150, "%sSolid Boost Enabled.", msg ); + new ida[1]; + ida[0] = id; + set_task( 15.0, "solid_boost_timer", 150 + id, ida, 1 ); + if( timer[ id ][ TMR_CFLAGS ] & CF_START ) timer[ id ][ TMR_CNTBST ]++; + } + else if( newboost == CF_SUPER_JUMP && boost_enabled( id, SJUMP, silent ) ) + format( msg, 150, "%sSuper Jump Enabled.", msg ); + else if( newboost == CF_DOUBLE_JUMP && boost_enabled( id, DJUMP, silent ) ) + format( msg, 150, "%sDouble Jump Enabled.", msg ); + else return; + timer[ id ][ TMR_CFLAGS ] += newboost; } - if(strlen(msg))clmsg(id,msg) - return PLUGIN_HANDLED + clmsg( id, msg ); } //Task to auto disable solid boost after timeout public solid_boost_timer( ida[] ) change_boost( ida[0], CF_SOLID ) -/*public server_frame( ) -{//Semi-clip - if( get_pcvar_num( p_climb ) ) +//Semi-clip +public server_frame( ) +{ + if( !get_pcvar_num( p_climb ) ) return FMRES_IGNORED + + new players[32], num, i, j, Float:c1[3], Float:c2[3]; + new Float:c1z[3], Float:c2z[3]; + new id_i, id_j, cflags_i, cflags_j; + get_players( players, num, "ach" ); + + //new Float:c1d[3],Float:c2d[3],xyadd,zadd + for( i = 0; i < num; i++ ) { - new players[32], bool:skip[32], num, i, j - new Float:orig_i[3], Float:orig_j[3] - new Float:vel_i[3], Float:vel_iz[3] - new id_i, id_j, cflags_i, cflags_j - get_players( players, num, "ac" ) - for( i = 0; i < num; i++ ) - { - id_i = players[i] - cflags_i = timer[id_i][TMR_CFLAGS] - - if( !( cflags_i & CF_PAUSE ) ) - { - entity_get_vector( id_i, EV_VEC_origin, orig_i ) - entity_get_vector( id_i, EV_VEC_velocity, vel_i ) - - vel_iz[0] = vel_i[0] > 0 ? -70.0 : 70.0 - vel_iz[1] = vel_i[1] > 0 ? -70.0 : 70.0 - vel_iz[2] = vel_i[2] > 0 ? -120.0 : 120.0 - - if( !vel_i[0] ) vel_i[0] = vel_iz[0] * -1 - if( !vel_i[1] ) vel_i[1] = vel_iz[1] * -1 - if( !vel_i[2] ) vel_i[2] = vel_iz[2] * -1 - - for( j=0; j 9 ) sc_fcount = 0 - - //Semi-clip - new players[32],num,i,j,Float:c1[3],Float:c2[3] - new Float:c1z[3],Float:c2z[3] - new id_i,id_j,cflags_i,cflags_j - get_players(players,num,"ac") - //new Float:c1d[3],Float:c2d[3],xyadd,zadd - for(i=0;i25&&vector_distance(c1z,c2z)>30)){ - unsolid(id_i) - unsolid(id_j) - j=num + + + //Semiclip touch detection + if( pev( id_i, pev_solid ) == SOLID_NOT ) + { + new class[9], ptr, Float:v_orig[3]; + pev( id_i, pev_origin, v_orig ); + //v_orig[2] -= 18; + v_orig[2] -= 10; + + new ent = engfunc( EngFunc_FindEntityInSphere, MAXPLAYERS, v_orig, 16.0 ); + while( ent > MAXPLAYERS ) + { + pev( ent, pev_classname, ptr, class, 8 ); + //trigger_teleport, trigger_once, trigger_multiple, trigger_gravity, trigger_push, trigger_hurt, func_door + //if( equal( class, "trigger_", 8 ) || equal( class, "func_", 5 ) && !equal( class, "func_water" ) ) + if( equal( class, "trigger_teleport" ) || equal( class, "trigger_hurt" ) || + equal( class, "trigger_once" ) || equal( class, "trigger_multiple" ) || + equal( class, "trigger_gravity" ) || equal( class, "trigger_push" ) || + equal( class, "func_door" ) ) + { + dllfunc( DLLFunc_Touch, ent, id_i ); + //break; } - } + ent = engfunc( EngFunc_FindEntityInSphere, ent, v_orig, 16.0 ); } - if(j+1==num)solid(id_i) + } } } - return PLUGIN_CONTINUE + + return FMRES_IGNORED } stock bool:is_between_f( Float:mid, Float:a, Float:b ) @@ -1717,7 +1611,48 @@ if( !get_pcvar_num( p_climb ) || is_user_bot( id ) || !is_climber_alive( id ) ) return PLUGIN_CONTINUE - if( sclip[id] && sc_fcount == 9 ) entity_set_int( id, EV_INT_solid, SOLID_BBOX ) + /* + //Auto Semiclip + new Float:vOrig[3], ent, count, Float:range + + range = pev( id, pev_speed ) * 0.5 + 50.0 + + pev( id, pev_origin, vOrig ) + + //if( !( timer[ id ][ TMR_CFLAGS ] & CF_SOLID ) ) + //{ + ent = engfunc( EngFunc_FindEntityInSphere, -1, vOrig, range ) + while( ent <= MAXPLAYERS ) + { + if( ent != id ) + { + set_solid( ent, 0 ) + count++ + } + ent = engfunc( EngFunc_FindEntityInSphere, ent, vOrig, range ) + } + //} + if( count ) set_solid( id, 0 ) + else set_solid( id ) + + + //Semiclip touch detection + if( pev( id, pev_solid ) == SOLID_NOT ) + { + new class[9], ptr + //pev( id, pev_origin, vOrig ) + + new ent = engfunc( EngFunc_FindEntityInSphere, MAXPLAYERS, vOrig, 17.0 ) + while( ent > 0 ) + { + pev( ent, pev_classname, ptr, class, 8 ) + if( equal( class, "trigger_", 8 ) || equal( class, "func_", 5 ) ) + dllfunc( DLLFunc_Touch, ent, id ) + ent = engfunc( EngFunc_FindEntityInSphere, ent, vOrig, 17.0 ) + } + + } + */ //Detect button use. Replicated from HL SDK if( get_user_button( id ) & IN_USE && !( get_user_oldbutton( id ) & IN_USE ) ) @@ -1731,7 +1666,7 @@ { get_brush_entity_origin( entlist[i], orig ) if( is_in_viewcone( id, orig ) ) button_used( id, entlist[i] ) - } + } } } @@ -1802,8 +1737,6 @@ if( !( get_pcvar_num(p_climb) && get_pcvar_num(p_boost) && is_climber_alive( id ) ) || is_user_bot(id) ) return PLUGIN_CONTINUE - if( sclip[id] ) entity_set_int( id, EV_INT_solid, SOLID_NOT ) - if( _:get_distance( _:post_think_vel[id], { 0, 0, 0 } ) ) { entity_set_vector( id, EV_VEC_velocity, post_think_vel[id] ) @@ -1821,8 +1754,11 @@ { new Float:coords[3] entity_get_vector( id, EV_VEC_origin, coords ) - for( new i=0; i<3; i++ ) origins[id][ORIG_PAUS+i] = coords[i] - origins[id][ORIG_PAUS+3] = entity_get_float( id, EV_FL_gravity ) + + origins[id][ORIG_PAUSX] = coords[0] + origins[id][ORIG_PAUSY] = coords[1] + origins[id][ORIG_PAUSZ] = coords[2] + origins[id][ORIG_PAUSG] = entity_get_float( id, EV_FL_gravity ) } return PLUGIN_CONTINUE } @@ -1848,7 +1784,7 @@ //new cflags = timer[id][TMR_CFLAGS] - if( btn_type == 1 )//Start Button + if( btn_type == 1 && !check_timeout( id, time_stamps[id][TS_SPAWN], SPAWN_TIMEOUT ) )//Start Button { new Float:orig[3], bool:need_respawn = true //Float:view[3] if( timer[id][TMR_CFLAGS] & CF_START ) need_respawn = false @@ -1856,14 +1792,14 @@ for( new i = 0; i < 48; i++ ) origins[id][i] = 0.0 //Erase checkpoints //Set all associated variables - timer[id][TMR_STARTD] = get_systime() - change_status(id,CF_START) + timer[id][TMR_CNTTME] = 0 timer[id][TMR_CNTCPS] = 0 timer[id][TMR_CNTGCS] = 0 timer[id][TMR_CNTBST] = 0 timer[id][TMR_CPPOS] = 0 timer[id][TMR_CNTWPN] = 0 time_stamps[id][TS_BOOST] = BOOST_TIMEOUT + change_status(id,CF_START) if( timer[id][TMR_CFLAGS] & CF_COUNTDOWN ) set_countdown_time( id ) @@ -1892,7 +1828,7 @@ case 2:client_cmd( id, "spk barney/c1a2_ba_climb" ) } - change_boost( id, CF_NULL ) //Disable Boosts + change_boost( id, CF_NULL, SILENT ) //Disable Boosts //time_stamps[id][TS_BOOST]=0 clmsg(id,"Timer started. Go Go Go!!!") //client_print(id,print_chat,"Timer started. Go Go Go!!!") @@ -1903,10 +1839,15 @@ } else if( btn_type == 2 )//Finish Button { - if( timer[id][TMR_CFLAGS] & CF_START) + if( timer[id][TMR_CFLAGS] & CF_START ) { + new cnttme = timer[id][TMR_CNTTME] / 10 + new cntbst = timer[id][TMR_CNTBST] + new cntcps = timer[id][TMR_CNTCPS] + new cntgcs = timer[id][TMR_CNTGCS] + new cntwpn = timer[id][TMR_CNTWPN] + //Set client variables - timer[id][TMR_FINISH] = get_systime( ) change_status( id, CF_STOP ) timer[id][TMR_SESFIN]++ timer[id][TMR_MAPFIN]++ @@ -1915,38 +1856,39 @@ if( get_pcvar_num( p_sounds ) ) client_cmd( 0, "spk woop" ) clmsg( id, "Congratulations 1337 climber." ) //client_print(id,print_chat,"Congratulations 1337 climber.") - new name[32], msg[21] - formatex( msg, sizeof( msg ) - 1, "%s^t%s", getuserstatus( id ), parsetime( get_climber_time( id ) ) ) + new name[32], msg[23] + formatex( msg, 22, "%s^t%s", getuserstatus( id ), parsetime( timer[id][TMR_CNTTME] ) ) //clmsg(id,msg) //client_print(id,print_chat,msg) new wpn[11] - get_weapon_name( timer[id][TMR_CNTWPN], wpn, 10 ) + get_weapon_name( cntwpn, wpn, 10 ) //Announce to all get_user_name( id, name, 32 ) - client_print( 0, print_chat, "%s^t%s^t(%s/ %d CPS/ %d GCS/ %d Boosts)^tCompleted (%d, %d)", - name, msg, - wpn, timer[id][TMR_CNTCPS], timer[id][TMR_CNTGCS], timer[id][TMR_CNTBST], - timer[id][TMR_SESFIN], timer[id][TMR_MAPFIN] ) + client_print( 0, print_chat, + "%s^t%s^t(%s/ %d CPS/ %d GCS/ %d Boosts)^tCompleted (%d, %d)", + name, msg, wpn, cntcps, cntgcs, cntbst, + timer[id][TMR_SESFIN], timer[id][TMR_MAPFIN] + ) + + new cntscore = ( ( ( cntbst > 0 ? 1 : 0 ) * 1000000 ) + + ( ( cntcps > 0 ? 1 : 0 ) * 100000 ) + + ( cntwpn * 10000 ) + + cnttme ) - new cnt_score = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + - ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + - ( timer[id][TMR_CNTWPN] * 10000 ) + - get_climber_time( id ) ) - - new bst_score = ( ( ( timer[id][TMR_BSTBST] > 0 ? 1 : 0 ) * 1000000 ) + + new bstscore = ( ( ( timer[id][TMR_BSTBST] > 0 ? 1 : 0 ) * 1000000 ) + ( ( timer[id][TMR_BSTCPS] > 0 ? 1 : 0 ) * 100000 ) + ( timer[id][TMR_BSTWPN] * 10000 ) + - timer[id][TMR_BSTTME] ) + timer[id][TMR_BSTTME] / 10 ) - if( cnt_score < bst_score || bst_score == 0 ) + if( cntscore < bstscore || bstscore == 0 ) { - timer[id][TMR_BSTTME] = get_climber_time( id ) - timer[id][TMR_BSTCPS] = timer[id][TMR_CNTCPS] - timer[id][TMR_BSTGCS] = timer[id][TMR_CNTGCS] - timer[id][TMR_BSTBST] = timer[id][TMR_CNTBST] - timer[id][TMR_BSTWPN] = timer[id][TMR_CNTWPN] + timer[id][TMR_BSTTME] = cnttme + timer[id][TMR_BSTCPS] = cntcps + timer[id][TMR_BSTGCS] = cntgcs + timer[id][TMR_BSTBST] = cntbst + timer[id][TMR_BSTWPN] = cntwpn } sfexec( id, 2 )//Execute commands from start/finish config @@ -1972,40 +1914,39 @@ } //Execute commands from start/finish config -public sfexec(id,clevent){ - new clstat[3],cflags=timer[id][TMR_CFLAGS] - /*switch(timer[id][TMR_CFLAGS]){ - case TMR_CFLAGS_STOP: clstat="ns" - case TMR_CFLAGS_STRT: clstat="st" - case TMR_CFLAGS_FNSH: clstat="fn" - }*/ - if(is_finished(id))clstat="fn" - else if(cflags&CF_STOP)clstat="ns" - else if(cflags&CF_START)clstat="st" - //else if(timer[id][TMR_CFLAGS]&CF_FINISH)clstat="fn" - //if(equal(clstat,"ns")&&(get_user_flags(id)&VIP||timer[id][TMR_SESFIN]>0))clstat="fn" - - for(new i=0;i 0 ? 1 : 0 ) * 1000000 ) + ( ( timer[id][TMR_BSTCPS] > 0 ? 1 : 0 ) * 100000 ) + ( timer[id][TMR_BSTWPN] * 10000 ) + - timer[id][TMR_BSTTME] ) + timer[id][TMR_BSTTME] / 10 ) } else if( timer[id][TMR_CFLAGS] & CF_START || timer[id][TMR_CFLAGS] & CF_PAUSE ) {//Has time but no high score @@ -2057,7 +1998,7 @@ pdata[i][1] = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + ( timer[id][TMR_CNTWPN] * 10000 ) + - get_climber_time( id ) ) + timer[id][TMR_CNTTME] / 10 ) } else pdata[i][0] = 2 //No time or high score } @@ -2067,33 +2008,6 @@ players[i] = pdata[i][2] } -/*public get_limit(){ - //if(get_pcvar_num(p_webmod)) - //return 0 - new url[100] - get_pcvar_string(p_stats_url,url,99) - if(strlen(url)) - return false - return true -}*/ - -/*public get_url( id, file[] ) -{ - new url[100] - get_pcvar_string( p_stats_url, url, 99 ) - //if(get_pcvar_num(p_webmod)){ - // new ip[10],iip[33],eip[33],port[10] - // get_user_ip(id,ip,9) - // get_pcvar_string(p_ip_internal,iip,32) - // get_pcvar_string(p_ip_external,eip,32) - // get_pcvar_string(p_port,port,9) - // if(equal(ip,"192.168.",8))format(url,99,"http://%s:%s/%s",iip,port,file) - // else format(url,99,"http://%s:%s/%s",eip,port,file) - //} - if( strlen( url ) ) format( url, 99, "%sclimb_scores.html", url ) - return url -}*/ - stock sb_add_tabs( str[], size) { new len = strlen( str )// > 7 ? 1 : 2 @@ -2103,98 +2017,90 @@ public climbscores( id ) {//Show scoreboard - if( get_pcvar_num( p_climb ) ) + if( !get_pcvar_num( p_climb ) ) return PLUGIN_HANDLED + + if( get_systime() - ts_score > 2 ) { - if( get_systime() - ts_score > 2 ) + new fh = fopen( SCORES_PATH, "w" ) + + //Header-8 cols: #, name, status, time, sct/cp/gc/boost, Best, cp/gc/boost, Completed + fprintf( fh, "" ) + fprintf( fh, "
" ) + fprintf( fh, "
#	Name		Status		Time	Wpn/CP/GC/Bst	Best	...		Fin
" ) + fprintf( fh, "
" )
+		
+		new line[251], name[NAMELEN+2], players[32], num, tid, written_len
+		new ctime, cwpn, ccp, cgc, cbst
+		new btime, bwpn, bcp, bgc, bbst
+		new ctime_str[20], btime_str[20]
+		
+		get_players_ordered( players, num )
+		
+		for( new i = 0; i < num; i++ )
 		{
-			new fh = fopen( SCORES_PATH, "w" )
-			
-			//Header-8 cols: #, name, status, time, sct/cp/gc/boost, Best, cp/gc/boost, Completed
-			fprintf( fh, "" )
-			fprintf( fh, "
" ) - fprintf( fh, "
#	Name		Status		Time	Wpn/CP/GC/Bst	Best	...		Fin
" ) - fprintf( fh, "
" )
+			tid = players[i]
 			
-			new line[251], name[NAMELEN+2], players[32], num, tid, written_len
-			new ctime, cwpn, ccp, cgc, cbst
-			new btime, bwpn, bcp, bgc, bbst
-			new ctime_str[20], btime_str[20]
+			get_user_name( tid, name, NAMELEN)
+			sb_add_tabs( name, NAMELEN+2 )
 			
-			get_players_ordered( players, num )
+			ctime = timer[tid][TMR_CNTTME]
+			cwpn = timer[tid][TMR_CNTWPN]
+			ccp = timer[tid][TMR_CNTCPS]
+			cgc = timer[tid][TMR_CNTGCS]
+			cbst = timer[tid][TMR_CNTBST]
+			format( ctime_str, 19, "%d/%d/%d/%d", cwpn, ccp, cgc, cbst )
+			sb_add_tabs( ctime_str, 19 )
+			
+			btime = timer[tid][TMR_BSTTME]
+			bwpn = timer[tid][TMR_BSTWPN]
+			bcp = timer[tid][TMR_BSTCPS]
+			bgc = timer[tid][TMR_BSTGCS]
+			bbst = timer[tid][TMR_BSTBST]
+			format( btime_str, 19, "%d/%d/%d/%d", bwpn, bcp, bgc, bbst )
+			sb_add_tabs( btime_str, 19 )
 			
-			for(new i = 1; i <= num; i++ )
-			{
-				tid = players[i]
-				
-				get_user_name( tid, name, NAMELEN)
-				sb_add_tabs( name, NAMELEN+2 )
-				
-				ctime = get_climber_time(tid)
-				cwpn = timer[tid][TMR_CNTWPN]
-				ccp = timer[tid][TMR_CNTCPS]
-				cgc = timer[tid][TMR_CNTGCS]
-				cbst = timer[tid][TMR_CNTBST]
-				format( ctime_str, 19, "%d/%d/%d/%d", cwpn, ccp, cgc, cbst )
-				sb_add_tabs( ctime_str, 19 )
-				
-				btime = timer[tid][TMR_BSTTME]
-				bwpn = timer[tid][TMR_BSTWPN]
-				bcp = timer[tid][TMR_BSTCPS]
-				bgc = timer[tid][TMR_BSTGCS]
-				bbst = timer[tid][TMR_BSTBST]
-				format( btime_str, 19, "%d/%d/%d/%d", bwpn, bcp, bgc, bbst )
-				sb_add_tabs( btime_str, 19 )
-				
-				formatex( line, 250,
-					"%s%d	%s%s	%s	%s%s	%s%d%s",
-					i % 2 ? NULLSTR : "
", - i, htmlspecialchars( name ), - getuserstatus( tid ), - parsetime( ctime ), ctime_str, - parsetime( btime ), btime_str, - timer[tid][TMR_MAPFIN], - i % 2 ? NULLSTR : "
" ) - written_len += strlen( line ) - //if( limit && written_len > ( 1263 - strlen( cust_msg ) ) ) break - if( written_len > 1263 ) break - fprintf( fh, line ) - } - //1530-150-117=1263 - new cust_msg[33] - get_pcvar_string( p_stats_msg, cust_msg, 32 ) - if( !strlen( cust_msg ) ) formatex( cust_msg, 32, "Climb %s", VERSION ) - fprintf( fh, "
%s
", cust_msg ) - fclose( fh ) - ts_score = get_systime() - } - - show_motd( id, SCORES_PATH, "Current Scores" ) + formatex( line, 250, + "%s%d %s%s %s %s%s %s%d%s", + i % 2 ? NULLSTR : "
", + i + 1, htmlspecialchars( name ), + getuserstatus( tid ), + parsetime( ctime ), ctime_str, + parsetime( btime ), btime_str, + timer[tid][TMR_MAPFIN], + i % 2 ? NULLSTR : "
" ) + written_len += strlen( line ) + //if( limit && written_len > ( 1263 - strlen( cust_msg ) ) ) break + if( written_len > 1263 ) break + fprintf( fh, line ) + } + //1530-150-117=1263 + new cust_msg[33] + get_pcvar_string( p_stats_msg, cust_msg, 32 ) + if( !strlen( cust_msg ) ) formatex( cust_msg, 32, "Climb %s", VERSION ) + fprintf( fh, "
%s
", cust_msg ) + fclose( fh ) + ts_score = get_systime() } + + show_motd( id, SCORES_PATH, "Current Scores" ) + return PLUGIN_HANDLED } -public parsetime(sec){//Convert seconds to time string with zero padded seconds field - new timestr[9],mins - mins=sec/60 - sec=sec%60 - formatex(timestr,8,"%d:%s%d",mins,sec<10?"0":"",sec) +//Convert seconds to time string with zero padded seconds field +public parsetime( decisec ) +{ + new timestr[11], mins, sec, dec, decstr[3] + + sec = decisec / 10 + dec = decisec % 10 + mins = sec / 60 + sec = sec % 60 + if( dec ) formatex( decstr, 2, ".%d", dec ) + formatex( timestr, 10, "%d:%s%d%s", mins, sec < 10 ? "0" : NULLSTR , sec, decstr ) return timestr } -public get_climber_time( id ) -{//Calculate client climb time in seconds - /*new ptime,cflags=timer[id][TMR_CFLAGS] - ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] - if(cflags&CF_STOP&&timer[id=1][TMR_SESFIN]>0)ptime=timer[id][TMR_FINISH]-timer[id][TMR_STARTD] - else if(cflags&CF_STOP)ptime=0 - else if(cflags&CF_START)ptime=get_systime()-timer[id][TMR_STARTD] - else if(cflags&CF_PAUSE)ptime=timer[id][TMR_STARTD]*/ - new cflags = timer[id][TMR_CFLAGS] - if( cflags & CF_START ) return get_systime()-timer[id][TMR_STARTD] - else if( cflags & CF_PAUSE ) return timer[id][TMR_STARTD] - return timer[id][TMR_FINISH]-timer[id][TMR_STARTD] -} - public hudtime( ) {//Set clock on HUD to current climb time if( !get_pcvar_num( p_climb ) ) return @@ -2205,17 +2111,17 @@ { id = players[i] cflags = timer[id][TMR_CFLAGS] - cltime = get_climber_time(id) + 1 + cltime = timer[id][TMR_CNTTME] / 10 + 1 if( cflags & CF_PAUSE ) { clmsg( id, "PAUSED - say '/unpause' to resume." ) cl_pause( id ) } - if( !( cflags & CF_COUNTDOWN ) || ( timer[id][TMR_BSTTME] - get_climber_time( id ) < 0 ) ) + if( !( cflags & CF_COUNTDOWN ) || ( timer[id][TMR_BSTTME] >= timer[id][TMR_CNTTME] ) ) hudtime_msg( id, cltime ) else if( cflags & CF_PAUSE ) - hudtime_msg( id, timer[id][TMR_BSTTME] - cltime + 1 ) + hudtime_msg( id, timer[id][TMR_BSTTME] / 10 - cltime + 1 ) for( new j = 1; j <= spec_ids[id][0]; j++ ) hudtime_msg( spec_ids[id][j], cltime ) @@ -2237,12 +2143,12 @@ public bool:set_countdown_time( id ) { - new bsttime = timer[id][TMR_BSTTME] - if( bsttime > 0 ) + new bsttme = timer[id][TMR_BSTTME] / 10 + if( bsttme > 0 ) { new cflags = timer[id][TMR_CFLAGS] if( cflags & CF_START || cflags & CF_PAUSE ) - hudtime_msg( id, timer[id][TMR_BSTTME] - get_climber_time( id ) ) + hudtime_msg( id, bsttme - timer[id][TMR_CNTTME] / 10 ) return true } clmsg( id, "Countdown disabled: No high score available." ) @@ -2274,50 +2180,76 @@ stock clmsg( id, msg[] ) {//Show Hud Message + //if( !strlen( msg ) ) return PLUGIN_HANDLED; set_hudmessage( get_pcvar_num( p_msg_r ), get_pcvar_num( p_msg_g ), get_pcvar_num( p_msg_b ), - get_pcvar_float( p_msg_x ), get_pcvar_float( p_msg_y ), 0, 0.0, 5.0, 0.5, 0.5, 4 ) - show_hudmessage( id, msg ) + get_pcvar_float( p_msg_x ), get_pcvar_float( p_msg_y ), 0, 0.0, 5.0, 0.5, 0.5, 4 ); + show_hudmessage( id, msg ); //Show to spectators for( new i = 1; i <= spec_ids[id][0]; i++ ) - show_hudmessage( spec_ids[id][i], msg ) - - return PLUGIN_HANDLED + show_hudmessage( spec_ids[id][i], msg ); + + return PLUGIN_HANDLED; } + //Fill spectator data array used for msg replication -public spec_update(){ - if(get_pcvar_num(p_climb)){ - new players[32],num,id,id2,i - for(i=1;i<33;i++)spec_ids[i][0]=0 - get_players(players,num,"bch") - for(i=0;i -1 ) - { - //Finished can stand on bhop blocks - if( is_finished( id ) ) - return PLUGIN_HANDLED - - if( bhop_failid[id] != ent ) - { - bhop_failid[id] = ent - bhop_fail[id] = false - - new tskid = TSK_BHOP + id - if( task_exists( tskid ) ) - remove_task( tskid ) - set_task( 0.2, "bhop_set_fail", tskid ) - tskid = TSK_CLEAR_FAIL + id - if( task_exists( tskid ) ) - remove_task( tskid ) - set_task( 0.7, "bhop_clear_fail", tskid ) - } - else if( bhop_fail[id] ) - { - teleport( id, door_tp_pos[dpos] ) - bhop_failid[id] = 0 - bhop_fail[id] = false - } - return PLUGIN_HANDLED - } - return PLUGIN_CONTINUE } -public door_in_array( door ) -{ - for( new i = 0; i < door_count; i++ ) - if( func_doors[i][0] == door ) - return i - return -1 -} - -public bhop_set_fail( tskid ) -{ - bhop_fail[tskid-TSK_BHOP] = true - return PLUGIN_HANDLED -} - -public bhop_clear_fail( tskid ) -{ - new id = tskid - TSK_CLEAR_FAIL - bhop_failid[id] = 0 - bhop_fail[id] = false - return PLUGIN_HANDLED -} - -//////////////////////////////////////////////////////////////////////////////// -// End: Multiplay Bunny Hop functions -//////////////////////////////////////////////////////////////////////////////// - -/*public spawn_distance_sort(elem1[],elem2[]){ - if(elem1[1]elem2[1])return 1 - return 0 -}*/ - //Future use, to block hook, or detect hook cheaters a.k.a. hookers public phook( id ) { @@ -2620,14 +2475,14 @@ new Float:c2[3], player, players[32], num get_players( players, num, "ac" ) - unsolid( id ) + set_solid( id, 0 ); for( new i = 0; i < num; i++ ) { player = players[i] if( id != player ) { entity_get_vector( player, EV_VEC_origin, c2 ) - if( vector_distance( orig, c2 ) < 90 ) unsolid( player ) + if( vector_distance( orig, c2 ) < 90 ) set_solid( player, 0 ); } } entity_set_vector( id, EV_VEC_velocity, Float:{0.0, 0.0, 0.0} ) @@ -2647,10 +2502,16 @@ set_entity_flags(ida[0],FL_DUCKING,1) } -public cvar_enabled(id,p_cvar){//Used in IF statements to automatically print error if false - if(get_pcvar_num(p_cvar)==0){ - clmsg(id,"This command is disabled.") - client_print(id,print_chat,"This command has been disabled by the server administrator.") +//Used in IF statements to automatically print error if false +stock cvar_enabled( id, p_cvar, silent = 0 ) +{ + if( get_pcvar_num(p_cvar) == 0 ) + { + if( !silent ) + { + clmsg( id, "This command is disabled." ) + client_print(id,print_chat,"This command has been disabled by the server administrator.") + } return 0 } return 1 @@ -2725,21 +2586,21 @@ if( get_pcvar_num( p_climb ) ) show_motd( id, "http://ian.cammarata.us/projects/climb/help/2a3/en/boosts?agent=hl", "Climb Plugin Help" ) +//Admin command, teleport to client public goto_player( id ) -{//Admin command, teleport to client - if( is_finished( id ) && get_pcvar_num( p_climb ) ) - { - new tid, arg[24] - read_argv( 1, arg, sizeof( arg ) - 1 ) - tid = cmd_target( tid, arg, 4 ) - if( tid ) - { - new Float:orig[3] - entity_get_vector( tid, EV_VEC_origin, orig ) - teleport( id, orig ) - } +{ + if( !is_finished( id ) || !get_pcvar_num( p_climb ) ) + return + + new tid, arg[24] + read_argv( 1, arg, 23 ) + tid = cmd_target( tid, arg, 4 ) + if( tid ) + { + new Float:orig[3] + entity_get_vector( tid, EV_VEC_origin, orig ) + teleport( id, orig ) } - return PLUGIN_HANDLED } public spectate( id ) @@ -2748,37 +2609,24 @@ { if( !is_climber_alive( id ) ) { - /* - cs_set_user_team(id,3)//fixes respawn bug? - frespawn( id ) - */ - climb_user_spawn( id ) - if( timer[id][TMR_CFLAGS] & CF_PAUSE ) + //already does this in the resethud function + /*if( timer[id][TMR_CFLAGS] & CF_PAUSE ) {//If they are paused tp to pause spot and freeze them again. new Float:coords[3] - for( new i=0; i<3; i++ ) coords[i] = origins[ id - 1 ][ ORIG_PAUS + i ] + + coords[0] = origins[ id ][ ORIG_PAUSX ] + coords[1] = origins[ id ][ ORIG_PAUSY ] + coords[2] = origins[ id ][ ORIG_PAUSZ ] + teleport( id, coords ) cl_pause( id ) - } + }*/ } else if( get_user_flags( id ) & VIP ? 1 : ( cvar_enabled( id, p_allow_spectators ) ) ) { - //Move client way outside the map so we don't have to see their retarded model - new Float:orig[3] - entity_get_vector( id, EV_VEC_origin, orig ) - entity_set_vector( id, EV_VEC_origin, Float:{ 99999.9, 99999.9, 99999.9 } ) - - //Set a task to move them back to where they were originally - new ida[4] - ida[0] = id - ida[1] = _:orig[0] - ida[2] = _:orig[1] - ida[3] = _:orig[2] - set_task( 0.1, "tsk_spec_tp_back", _, ida, 4 ) - set_pev( id, pev_movetype, MOVETYPE_NOCLIP ) set_pev( id, pev_solid, SOLID_NOT ) set_pev( id, pev_effects, EF_NODRAW ) @@ -2813,7 +2661,7 @@ if(equal(cmd,"say")||equal(cmd,"say_team")){ read_argv(1,cmd,20) trim(cmd) - if(contain(cmd," ")>-1)return PLUGIN_CONTINUE + if( contain( cmd, " " ) > -1 ) return PLUGIN_CONTINUE } //Remove slashes @@ -3271,7 +3119,7 @@ server_ip char(15),\ user_id integer,\ map_name varchar(32),\ - fin_time integer,\ + fin_time float,\ cps integer,\ gcs integer,\ boosts integer,\ @@ -3436,12 +3284,11 @@ new query[351], mapname[33], data[1] data[0] = id get_mapname( mapname, 32 ) - /*formatex( query, 149, - "select fin_time, cps, gcs, fin_cnt, boosts, wpns from %sscores where user_id=%d and map_name=^"%s^";", - DB_PREFIX, timer[id][TMR_DBUSER], mapname )*/ + formatex( query, 350, - "select s.fin_time, s.cps, s.gcs, g.fin_cnt, s.boosts, s.wpns from %sscores s, (select user_id, count(*) fin_cnt from %sscores where map_name = ^"%s^" group by user_id) g where map_name = ^"%s^" and s.user_id = %d and g.user_id = %d", + "select s.fin_time, s.cps, s.gcs, g.fin_cnt, s.boosts, s.wpns from %sscores s, (select user_id, count(*) fin_cnt from %sscores where map_name = ^"%s^" group by user_id) g where map_name = ^"%s^" and s.user_id = %d and g.user_id = %d order by score", DB_PREFIX, DB_PREFIX, mapname, mapname, timer[id][TMR_DBUSER], timer[id][TMR_DBUSER] ) + SQL_ThreadQuery( DB_TUPLE, "db_load_handler", query, data, 1 ) } @@ -3455,20 +3302,20 @@ msg="^x04No stats available for this account on the current map." else { - new mapname[33],timestr[9] + new mapname[33], Float:fTmp get_mapname(mapname,32) - timer[id][TMR_BSTTME] = SQL_ReadResult( query, 0 ) + SQL_ReadResult( query, 0, fTmp ) + timer[id][TMR_BSTTME] = floatround( fTmp * 10 ) timer[id][TMR_BSTCPS] = SQL_ReadResult( query, 1 ) timer[id][TMR_BSTGCS] = SQL_ReadResult( query, 2 ) timer[id][TMR_MAPFIN] = SQL_ReadResult( query, 3 ) timer[id][TMR_BSTBST] = SQL_ReadResult( query, 4 ) timer[id][TMR_BSTWPN] = SQL_ReadResult( query, 5 ) - //timer[id][TMR_CFLAGS]+=SQL_ReadResult(query,5)?CF_BSTSCT:0 + //timer[id][TMR_CFLAGS]+=SQL_ReadResult(query,5)?CF_BSTSCT:0 //Read cflag preferences from db, maybe this should be setinfos instead - timestr = parsetime(timer[id][TMR_BSTTME]) formatex( msg, 99, "^x04Stats loaded for %s - %s^t(%d/ %d CP/%d GC/%d Boost)^tCompleted %d", - mapname, timestr, timer[id][TMR_BSTWPN], timer[id][TMR_BSTCPS], + mapname, parsetime( timer[id][TMR_BSTTME] ), timer[id][TMR_BSTWPN], timer[id][TMR_BSTCPS], timer[id][TMR_BSTGCS], timer[id][TMR_BSTBST], timer[id][TMR_MAPFIN] ) } saytext( id, id, msg ) @@ -3479,39 +3326,36 @@ public db_save( id ) { - if( timer[id][TMR_DBUSER] < 1 ) + new user_id = timer[id][TMR_DBUSER] + + if( user_id < 1 ) { auto_reg( id ) return PLUGIN_HANDLED } + new query[351], name[33], data[2] data[0] = id get_mapname( name, 32 ) strtolower( name ) - new user_id = timer[id][TMR_DBUSER] - new fin_time = get_climber_time( id ) + new cntbst = timer[id][TMR_CNTBST] + new cntcps = timer[id][TMR_CNTCPS] + new cntwpn = timer[id][TMR_CNTWPN] + + new score = ( ( ( cntbst > 0 ? 1 : 0 ) * 1000000 ) + + ( ( cntcps > 0 ? 1 : 0 ) * 100000 ) + + ( cntwpn * 10000 ) + + timer[id][TMR_CNTTME] / 10 ) - new wpn_rank = timer[id][TMR_CNTWPN] - - new score = ( ( ( timer[id][TMR_CNTBST] > 0 ? 1 : 0 ) * 1000000 ) + - ( ( timer[id][TMR_CNTCPS] > 0 ? 1 : 0 ) * 100000 ) + - ( wpn_rank * 10000 ) + - fin_time ) - - /*if( timer[id][TMR_MAPFIN] == 1 ) - formatex( query, 350, - "insert into %sscores (user_id, map_name, fin_time, cps, gcs, fin_cnt, boosts, wpns, score, server_time_stamp) values (%d, ^"%s^", %d, %d, %d, %d, %d, %d, %d, %d);",\ - DB_PREFIX, user_id, name, fin_time, timer[id][TMR_BSTCPS], timer[id][TMR_BSTGCS], timer[id][TMR_MAPFIN], timer[id][TMR_BSTBST], sctd, sort, get_systime() ) - else*/ formatex( query, 350, - "insert into %sscores (server_ip, user_id, map_name, fin_time, cps, gcs, boosts, wpns, score, server_time_stamp) values (^"%s^", %d, ^"%s^", %d, %d, %d, %d, %d, %d, %d)",\ - DB_PREFIX, DB_SERVER_ID, user_id, name, fin_time, timer[id][TMR_CNTCPS], timer[id][TMR_CNTGCS], timer[id][TMR_CNTBST], wpn_rank, score, get_systime() ) + "insert into %sscores (server_ip, user_id, map_name, fin_time, cps, gcs, boosts, wpns, score, server_time_stamp) values (^"%s^", %d, ^"%s^", %f, %d, %d, %d, %d, %d, %d)",\ + DB_PREFIX, DB_SERVER_ID, user_id, name, timer[id][TMR_CNTTME] * 0.1, cntcps, timer[id][TMR_CNTGCS], cntbst, cntwpn, score, get_systime() ) SQL_ThreadQuery(DB_TUPLE,"db_save_handler",query,data,2) data[1] = 0 get_user_name( id, name, 32 ) - formatex( query, 350, "update %splayers set alias=^"%s^" where user_id=%d;", DB_PREFIX, name, timer[id][TMR_DBUSER] ) + formatex( query, 350, "update %splayers set alias=^"%s^" where user_id=%d;", DB_PREFIX, name, user_id ) SQL_ThreadQuery( DB_TUPLE, "db_name_update_handler", query, data, 2 ) return PLUGIN_HANDLED } @@ -3594,12 +3438,6 @@ formatex(query,99,"insert into %splayers (user_name,password,alias) values (^"%s^",^"%s^",^"%s^")",DB_PREFIX,user,pass,name) SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) } - //Else register SteamID - /*else if(timer[id][TMR_DBUSER]<1){ - data[1]=2 - formatex(query,99,"insert into %splayers (steam_id,alias) values (^"%s^",^"%s^")",DB_PREFIX,sid,name) - SQL_ThreadQuery(DB_TUPLE,"reg_handler",query,data,43) - }*/ } else client_print(id,print_console,"[Climb] Registration Error: Can't Register; Stats not enabled.") } @@ -3645,7 +3483,7 @@ } public highscores(id) -{//Show High Scores +{ if( !CLIMB_SAVE ) return clmsg( id, "Stats not enabled.") new hsurl[150], mapname[33] @@ -3661,12 +3499,11 @@ { new query[501], data[1] data[0] = id - /*formatex( query, 249,\ - "select p.alias, s.fin_time, s.cps, s.gcs, s.fin_cnt, s.boosts, s.wpns from %sscores s, %splayers p where s.map_name=^"%s^" and p.user_id=s.user_id order by s.score, s.fin_time limit 20;",\ - DB_PREFIX, DB_PREFIX, mapname )*/ + formatex( query, 500, "select distinct p.alias, s.fin_time, s.cps, s.gcs, g.fin_cnt, s.boosts, s.wpns, s.score from %sscores s join %splayers p on s.user_id = p.user_id join (select user_id, min(score) minscore, count(*) fin_cnt from %sscores where map_name=^"%s^" group by user_id, wpns) g on p.user_id=g.user_id where map_name=^"%s^" and s.score=g.minscore order by s.score limit 20", DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) + SQL_ThreadQuery( DB_TUPLE, "hs_handler", query, data, 1 ) ts_hscore = get_systime() } @@ -3710,18 +3547,22 @@ sb_add_tabs( name, NAMELEN+2 ) - format( btime_str, 19, "%d/%d/%d/%d",\ - SQL_ReadResult( query, 6 ),\ - SQL_ReadResult( query, 2 ),\ - SQL_ReadResult( query, 3 ),\ - SQL_ReadResult( query, 5 ) ) + format( btime_str, 19, "%d/%d/%d/%d", + SQL_ReadResult( query, 6 ), + SQL_ReadResult( query, 2 ), + SQL_ReadResult( query, 3 ), + SQL_ReadResult( query, 5 ) + ) sb_add_tabs( btime_str, 19 ) + new Float:fTmp + SQL_ReadResult( query, 1, fTmp ) + formatex( line, 150,\ "%s%d %s%s %s %d%s", i % 2 ? NULLSTR : "
", i, htmlspecialchars( name ), - parsetime( SQL_ReadResult( query, 1 ) ), + parsetime( floatround( fTmp * 10 ) ), btime_str, SQL_ReadResult( query, 4 ), i % 2 ? NULLSTR : "
" ) @@ -3774,9 +3615,6 @@ new query[501], data[1] data[0]=id - /*formatex( query, 500, - "select p.alias, s.score_id, s.fin_time, s.cps, s.gcs, s.boosts, s.wpns from %sscores s, %splayers p where s.map_name=^"%s^" and p.user_id=s.user_id order by s.score, s.fin_time limit 20;", - DB_PREFIX, DB_PREFIX, mapname)*/ formatex( query, 500, "select distinct p.alias, s.score_id, s.fin_time, s.cps, s.gcs, s.boosts, s.wpns from %sscores s join %splayers p on s.user_id = p.user_id join (select user_id, min(score) minscore, count(*) fin_cnt from %sscores where map_name=^"%s^" group by user_id, wpns) g on p.user_id=g.user_id where map_name=^"%s^" and s.score=g.minscore order by s.score limit 20", DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) @@ -3968,9 +3806,10 @@ //////////////////////////////////////////////////////////////////////////////// // End: Database functions //////////////////////////////////////////////////////////////////////////////// -public rotwtf( string[], out_len ) -{//Simple Password Encryption - new len=strlen( string ),str[99],cnt=0,tok=len-1 +//Simple Password Encryption +public rotwtf( string[], out_len )//I should replace this with md5 since it's available now +{ + new len = strlen( string ), str[99], cnt = 0, tok = len - 1 copy( str, out_len, string ) for( new index=0; index<11; index++ ) {