128 |
+: Cvars mp_autoteambalance and mp_limitteams are set to 0 when a start button is found, and reverted when the map changes. |
+: Cvars mp_autoteambalance and mp_limitteams are set to 0 when a start button is found, and reverted when the map changes. |
129 |
+: Support for a2 maps start/finish buttons. |
+: Support for a2 maps start/finish buttons. |
130 |
+: Commands measure and measure2. |
+: Commands measure and measure2. |
|
+: Multiplayer friendly bhops. |
|
131 |
+: Command 'weapons', gives client one of each speed weapon. |
+: Command 'weapons', gives client one of each speed weapon. |
132 |
+: Ranking by weapon speed. ex: If you beat a map with AWP, you'll be ranked above other weapon scores. |
+: Ranking by weapon speed. ex: If you beat a map with AWP, you'll be ranked above other weapon scores. |
133 |
+: Command countdown to have time countdown from your best time instead of counting up. |
+: Command countdown to have time countdown from your best time instead of counting up. |
268 |
#include <cstrike> |
#include <cstrike> |
269 |
#include <cstrike2> |
#include <cstrike2> |
270 |
|
|
271 |
new const VERSION[ ] = "a3.7.3 Nov 18 16:34 MST" |
new const VERSION[ ] = "a3.7.4 Nov 24 15:41 MST" |
272 |
new const TRKCVAR[ ] = "climb_version" |
new const TRKCVAR[ ] = "climb_version" |
273 |
|
|
274 |
new const DONOTHING[ ] = "donothing" |
new const DONOTHING[ ] = "donothing" |
275 |
new const NULLSTR[ ] = "" |
new const NULLSTR[ ] = "" |
276 |
|
|
347 |
|
|
348 |
new LIMIT_TEAMS_OLD, TEAM_BALANCE_OLD |
new LIMIT_TEAMS_OLD, TEAM_BALANCE_OLD |
349 |
|
|
|
//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 } |
|
|
|
|
350 |
//Cvar Pointers |
//Cvar Pointers |
351 |
new p_climb, p_auto, p_boost, p_cpprice, p_startmoney |
new p_climb, p_auto, p_boost, p_cpprice, p_startmoney |
352 |
new p_msg_r, p_msg_g, p_msg_b, p_msg_x, p_msg_y |
new p_msg_r, p_msg_g, p_msg_b, p_msg_x, p_msg_y |
365 |
#define TSK_AUTORSPN 100 //100+: Auto Respawn |
#define TSK_AUTORSPN 100 //100+: Auto Respawn |
366 |
//#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer |
//#define TSK_BOOSTTMR 150 //150+: Solid Boost Timer |
367 |
#define TSK_FLIGHT 200 |
#define TSK_FLIGHT 200 |
368 |
#define TSK_BHOP 250 |
#define TSK_MEASURE2 250 |
|
#define TSK_CLEAR_FAIL 300 |
|
|
#define TSK_MEASURE2 350 |
|
369 |
|
|
370 |
//Status timer[id][TMR_CFLAGS]&=x |
//Status timer[id][TMR_CFLAGS]&=x |
371 |
#define CF_NULL 0 //Passed to change_boost() to remove all boost flags |
#define CF_NULL 0 //Passed to change_boost() to remove all boost flags |
574 |
} |
} |
575 |
} |
} |
576 |
|
|
|
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 |
|
|
} |
|
|
|
|
577 |
return PLUGIN_CONTINUE |
return PLUGIN_CONTINUE |
578 |
} |
} |
579 |
|
|
581 |
{ |
{ |
582 |
new ent, ent2, tmpstr[33], Float:tmpflt |
new ent, ent2, tmpstr[33], Float:tmpflt |
583 |
|
|
|
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 |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
584 |
//Store ent id's for start/fin buttons, some maps change target value after timer starts |
//Store ent id's for start/fin buttons, some maps change target value after timer starts |
585 |
ent = find_ent_by_class( -1, "func_button" ) |
ent = find_ent_by_class( -1, "func_button" ) |
586 |
while( ent > 0 ) |
while( ent > 0 ) |
2057 |
formatex( line, 250, |
formatex( line, 250, |
2058 |
"%s%d %s%s %s %s%s %s%d%s", |
"%s%d %s%s %s %s%s %s%d%s", |
2059 |
i % 2 ? NULLSTR : "<div>", |
i % 2 ? NULLSTR : "<div>", |
2060 |
i, htmlspecialchars( name ), |
i + 1, htmlspecialchars( name ), |
2061 |
getuserstatus( tid ), |
getuserstatus( tid ), |
2062 |
parsetime( ctime ), ctime_str, |
parsetime( ctime ), ctime_str, |
2063 |
parsetime( btime ), btime_str, |
parsetime( btime ), btime_str, |
2327 |
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
2328 |
// End: Auto Heal functions |
// End: Auto Heal functions |
2329 |
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
2330 |
// Start: Multiplay Bunny Hop functions |
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
2331 |
public pfn_touch( ent, id ) |
public pfn_touch( ent, id ) |
2332 |
{ |
{ |
2333 |
if( !get_pcvar_num( p_climb ) ) |
if( !get_pcvar_num( p_climb ) ) |
2352 |
} |
} |
2353 |
else return PLUGIN_HANDLED |
else return PLUGIN_HANDLED |
2354 |
|
|
|
if ( !ent || !id ) |
|
|
return PLUGIN_CONTINUE |
|
|
|
|
|
//Make sure id is player and ent is object |
|
|
if( 0 < ent <= MAXPLAYERS ) |
|
|
{ |
|
|
new tmp = id |
|
|
id = ent |
|
|
ent = tmp |
|
|
} |
|
|
else if( !( 0 < id <= MAXPLAYERS ) ) |
|
2355 |
return PLUGIN_CONTINUE |
return PLUGIN_CONTINUE |
|
|
|
|
//Bhop stuff |
|
|
new dpos = door_in_array( ent ) |
|
|
if( dpos > -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 |
|
2356 |
} |
} |
2357 |
|
|
|
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 |
|
|
//////////////////////////////////////////////////////////////////////////////// |
|
|
|
|
2358 |
/*public spawn_distance_sort(elem1[],elem2[]){ |
/*public spawn_distance_sort(elem1[],elem2[]){ |
2359 |
if(elem1[1]<elem2[1])return -1 |
if(elem1[1]<elem2[1])return -1 |
2360 |
if(elem1[1]>elem2[1])return 1 |
if(elem1[1]>elem2[1])return 1 |
3273 |
new query[351], mapname[33], data[1] |
new query[351], mapname[33], data[1] |
3274 |
data[0] = id |
data[0] = id |
3275 |
get_mapname( mapname, 32 ) |
get_mapname( mapname, 32 ) |
3276 |
/*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 )*/ |
|
3277 |
formatex( query, 350, |
formatex( query, 350, |
3278 |
"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", |
3279 |
DB_PREFIX, DB_PREFIX, mapname, mapname, timer[id][TMR_DBUSER], timer[id][TMR_DBUSER] ) |
DB_PREFIX, DB_PREFIX, mapname, mapname, timer[id][TMR_DBUSER], timer[id][TMR_DBUSER] ) |
3280 |
|
|
3281 |
SQL_ThreadQuery( DB_TUPLE, "db_load_handler", query, data, 1 ) |
SQL_ThreadQuery( DB_TUPLE, "db_load_handler", query, data, 1 ) |
3282 |
} |
} |
3283 |
|
|
3291 |
msg="^x04No stats available for this account on the current map." |
msg="^x04No stats available for this account on the current map." |
3292 |
else |
else |
3293 |
{ |
{ |
3294 |
new mapname[33] |
new mapname[33], Float:fTmp |
3295 |
get_mapname(mapname,32) |
get_mapname(mapname,32) |
3296 |
SQL_ReadResult( query, 0, timer[id][TMR_BSTTME] ) |
SQL_ReadResult( query, 0, fTmp ) |
3297 |
timer[id][TMR_BSTTME] *= 10 |
timer[id][TMR_BSTTME] = floatround( fTmp * 10 ) |
3298 |
timer[id][TMR_BSTCPS] = SQL_ReadResult( query, 1 ) |
timer[id][TMR_BSTCPS] = SQL_ReadResult( query, 1 ) |
3299 |
timer[id][TMR_BSTGCS] = SQL_ReadResult( query, 2 ) |
timer[id][TMR_BSTGCS] = SQL_ReadResult( query, 2 ) |
3300 |
timer[id][TMR_MAPFIN] = SQL_ReadResult( query, 3 ) |
timer[id][TMR_MAPFIN] = SQL_ReadResult( query, 3 ) |
3301 |
timer[id][TMR_BSTBST] = SQL_ReadResult( query, 4 ) |
timer[id][TMR_BSTBST] = SQL_ReadResult( query, 4 ) |
3302 |
timer[id][TMR_BSTWPN] = SQL_ReadResult( query, 5 ) |
timer[id][TMR_BSTWPN] = SQL_ReadResult( query, 5 ) |
3303 |
//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 |
3304 |
|
|
3305 |
formatex( msg, 99, |
formatex( msg, 99, |
3306 |
"^x04Stats loaded for %s - %s^t(%d/ %d CP/%d GC/%d Boost)^tCompleted %d", |
"^x04Stats loaded for %s - %s^t(%d/ %d CP/%d GC/%d Boost)^tCompleted %d", |
3492 |
formatex( query, 500, |
formatex( query, 500, |
3493 |
"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", |
"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", |
3494 |
DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) |
DB_PREFIX, DB_PREFIX, DB_PREFIX, mapname, mapname ) |
3495 |
|
|
3496 |
SQL_ThreadQuery( DB_TUPLE, "hs_handler", query, data, 1 ) |
SQL_ThreadQuery( DB_TUPLE, "hs_handler", query, data, 1 ) |
3497 |
ts_hscore = get_systime() |
ts_hscore = get_systime() |
3498 |
} |
} |
3544 |
) |
) |
3545 |
sb_add_tabs( btime_str, 19 ) |
sb_add_tabs( btime_str, 19 ) |
3546 |
|
|
3547 |
|
new Float:fTmp |
3548 |
|
SQL_ReadResult( query, 1, fTmp ) |
3549 |
|
|
3550 |
formatex( line, 150,\ |
formatex( line, 150,\ |
3551 |
"%s%d %s%s %s %d%s", |
"%s%d %s%s %s %d%s", |
3552 |
i % 2 ? NULLSTR : "<div>", |
i % 2 ? NULLSTR : "<div>", |
3553 |
i, htmlspecialchars( name ), |
i, htmlspecialchars( name ), |
3554 |
parsetime( SQL_ReadResult( query, 1 ) * 10 ), |
parsetime( floatround( fTmp * 10 ) ), |
3555 |
btime_str, |
btime_str, |
3556 |
SQL_ReadResult( query, 4 ), |
SQL_ReadResult( query, 4 ), |
3557 |
i % 2 ? NULLSTR : "</div>" ) |
i % 2 ? NULLSTR : "</div>" ) |