· 6 years ago · Jul 29, 2019, 12:32 PM
1#include <amxmodx>
2#include <amxmisc>
3#include <fakemeta>
4#include <engine>
5#include <fun>
6#include <colorchat>
7#include <dhudmessage>
8#pragma defclasslib sqlx sqlite
9#include <sqlx>
10
11#define SHOW_SC
12
13#define TASK_TELEPORT 12345
14
15#define VERSION "2.5"
16
17#define MAX_MARKERS 1500 //not the max marker NUMBER but ent's id
18
19new bool: find_origin = false
20
21new bool: allWant_duel, bool: pWant_duel[ 33 ], d_started, bool: teleporting_p[ 33 ] = false
22
23new g_pInCup = 0, g_pNumber = 0
24
25new Float:fPrepareTime
26
27new g_StartedName[ 32 ]
28
29new spec_nick[ 33 ][ 32 ]
30
31new Float:origins[ 33 ][ 3 ]
32new g_TimeCup = 1
33
34new r = 50, g = 35, b = 170
35
36new playerNum, players[ 32 ]
37
38new forbiden_say[][] = { "+hook", "say /nc", "say /pause", "say /noclip", "say_team /menu", "say /savepos", "say /spec",
39 "say_team /ct", "say_team /ct", "say_team /spec", "say_team /spec", "say_team /stuck", "say /stuck, say /menu" }
40
41new poss_forbiden[][] = { "say /cp", "say /tp", "say /gc", "say /checkpoint", "say_team /cp", "say_team /tp", "say_team /gc" }
42
43new saycmd[ 25 ]
44new poss_saycmd[ 25 ]
45
46new p_inDuel[ 33 ], currentPlayer[ 33 ] = 0
47
48new currMap[ 32 ]
49
50new Float:fOrigin[ MAX_MARKERS ][ 3 ]
51new ent[ MAX_MARKERS ]
52new g_mPos = 0
53new bool:g_fixCheck[ 33 ][ MAX_MARKERS ]
54new g_Model[] = "sprites/esp_friend.spr"
55new g_playerTouched[ 33 ]
56new g_pBestTouch[ 33 ]
57new bool:g_markerVis = false
58new filename[ 256 ]
59new Float:test_origin[ 3 ]
60
61new Handle:g_SQLTuple , g_szQueryCache[ 1024 ] , g_szSteamID[ 33 ][ 35 ], g_szName[ 33 ]
62
63new bool:g_pRead[ 33 ]
64new bool:faster_nc[ 33 ]
65
66new g_timetime[ 33 ]
67
68new Float:stime[ 33 ]
69new g_msgBarTime, g_hudInfo
70
71new g_InPro = true
72
73public plugin_init()
74{
75 register_plugin( "AUTOCUP Plugin", VERSION, "JocA" )
76
77 register_clcmd( "say /startcup", "duel_open_pre" )
78 register_clcmd( "say /joincup", "join_duel" )
79 register_clcmd( "say /exit", "exitCup" )
80 register_clcmd( "say /cupinfo", "showInfo" )
81
82 register_clcmd( "say /cup", "cup_menu" ) //admin menu
83
84 register_clcmd( "say /cup15", "cupTop15" ) //sqlite top15
85
86 register_concmd( "amx_cup_delete", "deletePlayer" ) //delete by steamid
87
88 register_forward( FM_CmdStart, "FwdCmdStart" ) // for faster noclip
89
90 register_cvar( "AutoCupKZ", "1", FCVAR_SERVER | FCVAR_SPONLY )
91
92 for( new i = 0; i < sizeof( forbiden_say ); i++ )
93 {
94 formatex( saycmd, charsmax( saycmd ), "%s", forbiden_say[ i ] )
95 register_clcmd( saycmd, "forbiden" )
96 }
97 for( new i = 0; i < sizeof( poss_forbiden ); i++ )
98 {
99 formatex( poss_saycmd, charsmax( poss_saycmd ), "%s", poss_forbiden[ i ] )
100 register_clcmd( poss_saycmd, "possibly_forbiden" )
101 }
102
103 get_mapname( currMap, 31 )
104 get_configsdir( filename, 255 )
105 format( filename, 255, "%s/Cup_maker/%s.txt", filename, currMap )
106
107 set_task( 2.0, "load_files", 0 )
108 set_task( 180.0, "showMsg", 0, .flags="b" )
109
110 g_msgBarTime = get_user_msgid( "BarTime" )
111 g_hudInfo = CreateHudSyncObj()
112
113 CreateTable()
114}
115public plugin_precache()
116{
117 precache_model( g_Model )
118}
119public plugin_end()
120{
121 SQL_FreeHandle(g_SQLTuple)
122}
123public FwdCmdStart( client, ucHandle ) //Hawk552 (Exolent)
124{
125 if( !is_user_alive( client )
126 || pev( client, pev_movetype ) != MOVETYPE_NOCLIP
127 || !( pev( client, pev_button ) & IN_FORWARD ) || !faster_nc[ client ] )
128 {
129 return FMRES_IGNORED;
130 }
131
132 static Float:fForward, Float:fSide;
133 get_uc( ucHandle, UC_ForwardMove, fForward );
134 get_uc( ucHandle, UC_SideMove, fSide );
135
136 if( fForward == 0.0 && fSide == 0.0 )
137 {
138 return FMRES_IGNORED;
139 }
140
141 static Float:fMaxSpeed;
142 pev( client, pev_maxspeed, fMaxSpeed );
143
144
145 {
146 static Float:vOrigin[ 3 ];
147 pev( client, pev_origin, vOrigin );
148
149 static Float:vAngle[ 3 ];
150 pev( client, pev_v_angle, vAngle );
151 engfunc( EngFunc_MakeVectors, vAngle );
152 global_get( glb_v_forward, vAngle );
153
154 vOrigin[ 0 ] += ( vAngle[ 0 ] * 10.0 );
155 vOrigin[ 1 ] += ( vAngle[ 1 ] * 10.0 );
156 vOrigin[ 2 ] += ( vAngle[ 2 ] * 10.0 );
157
158 engfunc( EngFunc_SetOrigin, client, vOrigin );
159 }
160 return FMRES_IGNORED;
161}
162public possibly_forbiden( id )
163{
164 if( pWant_duel[ id ] && g_InPro )
165 {
166 ColorChat( id, RED, "^4[CUP]^1 It's not allowed in this cup." )
167 return PLUGIN_HANDLED
168 }
169 return PLUGIN_CONTINUE
170}
171public timer( id ) //DarkGL
172{
173 new poruka[55]
174 format( poruka, charsmax( poruka ), "Cup time: %02d:%02d sec; Players: %d", (g_timetime[ id ]/60), (g_timetime[ id ]%60), g_pInCup)
175
176 static msgStatusText=0;
177 if(!msgStatusText)
178 msgStatusText = get_user_msgid("StatusText");
179
180 g_timetime[ id ] -= 1
181 if( g_timetime[ id ] >= 1 && d_started && pWant_duel[ id ] )
182 {
183 message_begin(MSG_ONE_UNRELIABLE, msgStatusText, _, id);
184 write_byte(0);
185 write_string(poruka);
186 message_end();
187 set_task( 0.95, "timer", id )
188 }
189 else
190 {
191 message_begin(MSG_ONE_UNRELIABLE, msgStatusText, _, id);
192 write_byte(0);
193 write_string("");
194 message_end();
195 }
196 return PLUGIN_CONTINUE
197}
198public deletePlayer( id )
199{
200 if( !is_user_admin( id ) )
201 return PLUGIN_HANDLED
202
203 new Handle:SqlConnection , ErrorCode;
204 SqlConnection = SQL_Connect( g_SQLTuple , ErrorCode , g_szQueryCache , charsmax( g_szQueryCache ) );
205
206 if( SqlConnection == Empty_Handle )
207 set_fail_state( g_szQueryCache );
208
209 new szarg1[32]
210 read_argv( 1, szarg1, 32 )
211
212 if( containi( szarg1, "STEAM" ) != -1 )
213 {
214 formatex( g_szQueryCache, charsmax( g_szQueryCache ) , "DELETE FROM cup_info WHERE steamid='%s'", szarg1 );
215 SQL_ThreadQuery( g_SQLTuple , "SelectHandle" , g_szQueryCache , _, _ );
216
217
218 ColorChat( id, BLUE, "^4[CUP]^1 Successfully deleted:^4 %s", szarg1 )
219 }
220 return PLUGIN_HANDLED
221}
222public cupTop15( id )
223{
224 new Data[ 1 ]; Data[ 0 ] = id;
225 get_user_authid( id , g_szSteamID[ id ] , charsmax( g_szSteamID[] ) )
226
227 formatex( g_szQueryCache,charsmax( g_szQueryCache ),"SELECT * FROM ( SELECT *, (CAST( wins AS float )/CAST( cups AS float)) AS winns FROM cup_info ) ORDER BY winns*players DESC, cups DESC, wins DESC LIMIT 15;" )
228 SQL_ThreadQuery( g_SQLTuple, "cup15Format", g_szQueryCache, Data, sizeof( Data ) )
229}
230public cup15Format( FailState , Handle:Query , Error[] , Errcode , Data[] , DataSize )
231{
232 new g_sBuffer[2048]
233 if( FailState == TQUERY_CONNECT_FAILED )
234 {
235 return set_fail_state("Could not connect to SQL database." );
236 }
237 else if( FailState == TQUERY_QUERY_FAILED )
238 {
239 log_amx( "Query error: %s" , Error );
240 return set_fail_state( g_szQueryCache );
241 }
242 if( Errcode )
243 return log_amx( "Error on query: %s" , Error );
244
245 new id = Data[ 0 ];
246 new rows1 = SQL_NumResults( Query )
247 new Name[ 33 ][ 32 ], cups[ 20 ], wins[ 20 ], plrs[ 20 ]
248 new Float:skill_result
249
250 if( SQL_MoreResults( Query ) )
251 {
252 for(new i = 0 ; i < rows1 ; i++)
253 {
254 SQL_ReadResult( Query, 1, Name[ i ], 31 )
255
256 cups[ i ] = SQL_ReadResult( Query, 2 )
257 wins[ i ] = SQL_ReadResult( Query, 3 )
258 plrs[ i ] = SQL_ReadResult( Query, 4 )
259
260 SQL_NextRow(Query)
261 }
262 }
263
264 if( rows1 > 0 )
265 {
266
267 new iLen=0;
268 iLen = format( g_sBuffer[iLen], 2047, "<meta charset=utf-8><body><center><style type=^"text/css^">body {background: url(^"https://ak8.picdn.net/shutterstock/videos/83248/thumb/1.jpg^") no-repeat center center fixed;background-size: cover;}table{margin-top: 10px;font-size:11px;font-family: Tahoma;border-collapse: collapse;text-align:center;color: #ffe1c6;line-height: 19px;border-bottom: 1px solid;}")
269 iLen += format( g_sBuffer[iLen], 2047 - iLen, "thead {border-bottom: 1px solid #ffe1c6;color:#ffb777;} tbody:hover td {color: transparent;text-shadow: 0 0 1px #aaa} tr:hover td {color:#ffe1c6;text-shadow: 0 0 0 #fff}; </style><table width=90%%><thead><tr height=50px ><th width=5%%>#<th width=37%%>Name<th width=8%%>Cups<th width=8%%>Wins<th width=11%%>Played with<th width=10%%>Skill</thead>" )
270 for(new i = 0 ; i < rows1 ; i++)
271 {
272 skill_result = (float(wins[i])/(float(cups[i])))*plrs[i]
273
274 iLen += format( g_sBuffer[iLen], 2047 - iLen, "<tr><td>%d<td>%s<td>%d<td>%d<td>%d<td>%.01f", i + 1, Name[i], cups[i], wins[i], plrs[i], skill_result )
275
276
277
278 }
279 show_motd(id, g_sBuffer, "Top15 CUP")
280 }
281 return PLUGIN_HANDLED
282}
283stock clear(src[]) //secure the sql
284{
285 new len = strlen( src );
286 replace_all(src, len, "\", "\\");
287 replace_all(src, len, "'", "\'");
288 replace_all(src, len, "^"", "\^"");
289 replace_all(src, len, "^n", "\^n");
290 replace_all(src, len, "^r", "\^n");
291 replace_all(src, len, "^x1A", "\^x1A");
292 replace_all(src, len, "^x00", "\^x00");
293}
294public client_putinserver( id )
295{
296 if( is_user_bot( id ) )
297 return PLUGIN_HANDLED
298
299 g_pRead[ id ] = false
300 stime[ id ] = 15.0
301
302 new Data[ 1 ]; Data[ 0 ] = id;
303 get_user_authid( id , g_szSteamID[ id ] , charsmax( g_szSteamID[] ) );
304
305 formatex( g_szQueryCache, charsmax( g_szQueryCache ) , "SELECT * FROM cup_info WHERE steamid='%s';" , g_szSteamID[ id ] )
306 SQL_ThreadQuery( g_SQLTuple , "SelectHandle" , g_szQueryCache , Data , sizeof( Data ) )
307
308 set_task( 2.0, "loadPlayer", id )
309 set_task( 5.0, "showInfo", id )
310
311 return PLUGIN_HANDLED
312}
313public showMsg()
314{
315 ColorChat( 0, RED, "^4[CUP]^1 To start a a cup -^3 /startcup^1, for joining^3 /joincup^1 (or type^4 /cupinfo^1)")
316}
317public showInfo( id )
318{
319 set_hudmessage( 255, 85, 0, 0.65, 0.2, 0, 3.0, 9.0 )
320 ShowSyncHudMsg( id, g_hudInfo, "Server is using KZAutocup v2.5 plugin^n^n/startcup - to start a cup^n/joincup - to join a cup^n/exit - to leave^n/cup15 - to see cuptop" )
321}
322public loadPlayer( id )
323{
324 if( !g_pRead[ id ] )
325 {
326 new Data[ 1 ]; Data[ 0 ] = id;
327 get_user_name( id, g_szName, charsmax( g_szName ) )
328 clear(g_szName);
329 formatex( g_szQueryCache, charsmax( g_szQueryCache ) , "INSERT INTO cup_info(cups, wins, players, name, steamid) VALUES(0, 0, 0, '%s', '%s');" , g_szName, g_szSteamID[ id ] );
330 SQL_ThreadQuery( g_SQLTuple , "SelectHandle" , g_szQueryCache , Data , sizeof( Data ) );
331 g_pRead[ id ] = true
332 }
333}
334public set_winner( check )
335{
336 new Data[ 1 ];
337 for( new i = 0; i <= g_pInCup; i++ )
338 {
339 if( p_inDuel[ i ] == check )//winner
340 {
341 Data[ 0 ] = check
342 get_user_authid( check , g_szSteamID[ check ] , charsmax( g_szSteamID[] ) )
343 formatex( g_szQueryCache, charsmax( g_szQueryCache ) , "UPDATE cup_info SET cups=cups+1, wins=wins+1, players=players+%d-1 WHERE steamid='%s';" , g_pNumber, g_szSteamID[ check ] );
344 SQL_ThreadQuery( g_SQLTuple , "SelectHandle" , g_szQueryCache , Data , sizeof( Data ) );
345 }
346 else //all others
347 {
348 Data[ 0 ] = p_inDuel[ i ]
349 get_user_authid( p_inDuel[ i ] , g_szSteamID[ p_inDuel[ i ] ] , charsmax( g_szSteamID[] ) )
350 formatex( g_szQueryCache, charsmax( g_szQueryCache ) , "UPDATE cup_info SET cups=cups+1, players=players+%d-1 WHERE steamid='%s';" , g_pNumber, g_szSteamID[ p_inDuel[ i ] ] );
351 SQL_ThreadQuery( g_SQLTuple , "SelectHandle" , g_szQueryCache , Data , sizeof( Data ) );
352 }
353 }
354}
355
356public CreateTable() //by bugsy's post, hope he doesnt mind heh
357{
358 SQL_SetAffinity( "sqlite" );
359
360 g_SQLTuple = SQL_MakeDbTuple("", "", "", "cup_version_one" )
361
362 new Handle:SqlConnection , ErrorCode;
363 SqlConnection = SQL_Connect( g_SQLTuple , ErrorCode , g_szQueryCache , charsmax( g_szQueryCache ) );
364
365 if( SqlConnection == Empty_Handle )
366 set_fail_state( g_szQueryCache );
367
368 RunQuery( SqlConnection , "CREATE TABLE IF NOT EXISTS cup_info (steamid VARCHAR(35) UNIQUE, name CHAR(32), cups INTEGER, wins INTEGER, players INTEGER );" );
369}
370public RunQuery( Handle:SQLConnection , const szQuery[] )
371{
372 new Handle:Query = SQL_PrepareQuery( SQLConnection , szQuery );
373
374 if( !SQL_Execute( Query ) )
375 {
376 SQL_QueryError( Query , g_szQueryCache , 100 );
377 set_fail_state( g_szQueryCache );
378 }
379
380}
381public SelectHandle( FailState , Handle:Query , Error[] , Errcode , Data[] , DataSize )
382{
383 if( FailState == TQUERY_CONNECT_FAILED )
384 {
385 return set_fail_state("Could not connect to SQL database." );
386 }
387 else if( FailState == TQUERY_QUERY_FAILED )
388 {
389 log_amx( "Query error: %s" , Error );
390 return set_fail_state( g_szQueryCache );
391 }
392
393 if( Errcode )
394 return log_amx( "Error on query: %s" , Error );
395
396 new id = Data[ 0 ];
397
398
399 if ( SQL_NumResults( Query ) )
400 {
401 g_pRead[ id ] = true;
402 }
403 return PLUGIN_CONTINUE;
404}
405public load_files() //load markers
406{
407 new file = fopen( filename, "r" )
408 new line = 0
409
410 if( file )
411 {
412 new Data[ 150 ], file_origin[ 3 ][ 10 ]
413
414 while( fgets( file, Data, 149 ) )
415 {
416 line++
417 parse( Data, file_origin[ 0 ], 9, file_origin[ 1 ], 9, file_origin[ 2 ], 9 )
418
419 test_origin[ 0 ] = str_to_float( file_origin[ 0 ] )
420 test_origin[ 1 ] = str_to_float( file_origin[ 1 ] )
421 test_origin[ 2 ] = str_to_float( file_origin[ 2 ] )
422
423 create_marker( 0, 0 )
424 }
425 }
426}
427public forbiden( id )
428{
429 if( d_started && pWant_duel[ id ] )
430 {
431 ColorChat( id, RED, "^1[CUP] Sorry,^3 not possible^1 while in Cup." )
432 return PLUGIN_HANDLED
433 }
434 return PLUGIN_CONTINUE
435}
436public client_disconnect( id )
437{
438 remove_task( id )
439 if( pWant_duel[ id ] )
440 {
441 ColorChat( 0, BLUE, "Player from cup left the server :/" )
442 pWant_duel[ id ] = false
443 g_pInCup -= 1
444 if( g_pInCup <= 1 )
445 {
446 d_started = false
447 g_pInCup = 0
448 pWant_duel[ id ] = false
449 allWant_duel = false
450 fm_set_user_frozen( id, 0 )
451 teleporting_p[ id ] = false
452 g_TimeCup = 1
453 find_origin = false
454 currentPlayer[ id ] = 0
455
456 g_playerTouched[ id ] = 0
457 g_pBestTouch[ id ] = 0
458 ColorChat( 0, GREY, "^4[CUP]^1 All players left the cup, you can^4 /startcup^1 now" )
459 }
460 }
461}
462public cup_menu( id )
463{
464 if( !is_user_admin( id ) )
465 return PLUGIN_HANDLED
466
467 new menu_c_text[ 50 ]; formatex( menu_c_text, charsmax( menu_c_text ), "\yCup Markers Menu^n^n\wMarkers now:\y %d\w", g_mPos )
468 new menu_visible[ 100 ]; formatex( menu_visible, charsmax( menu_visible), "Markers visible: %s", g_markerVis ? "\yYes^n":"\dNo^n" )
469 new fasternc[ 100 ]; formatex( fasternc, charsmax( fasternc ), "\rFaster Noclip: %s", faster_nc[ id ] ? "\yYes":"\dNo" )
470 new menuC = menu_create( menu_c_text, "cup_m_handler" )
471
472 menu_additem( menuC, "Create new marker" )
473 menu_additem( menuC, menu_visible )
474
475 menu_additem( menuC, "Delete last marker" )
476 menu_additem( menuC, "Delete ALL markers^n" )
477
478 menu_additem( menuC, "\ySave ALL markers^n" )
479
480 menu_additem( menuC, fasternc )
481
482 menu_display( id, menuC )
483
484 return PLUGIN_CONTINUE
485}
486public cup_m_handler( id, menuC, itemC )
487{
488 if( itemC == MENU_EXIT )
489 {
490 faster_nc[ id ] = true
491 menu_destroy( menuC )
492 return PLUGIN_HANDLED
493 }
494
495 switch( itemC )
496 {
497 case 0:
498 {
499 create_marker( id, 1 )
500 }
501 case 1:
502 {
503 g_markerVis = !g_markerVis
504 for( new o = 1; o <= g_mPos; o++ )
505 {
506 if( !g_markerVis )
507 {
508 set_pev( ent[ o ], pev_rendermode, kRenderTransAlpha )
509 }
510 else
511 {
512 set_pev( ent[ o ], pev_rendermode, kRenderNormal )
513 }
514 }
515 }
516 case 2:
517 {
518 if( g_mPos > 0 )
519 {
520 ColorChat( id, RED, "^4[CUP]^1 Removed last marker." )
521 remove_marker( id, 0 )
522 }
523 else
524 ColorChat( id, RED, "^4[CUP]^1 There's zero markers, shame on you !" )
525 }
526 case 3:
527 {
528 remove_marker( id, 1 )
529 }
530 case 4:
531 {
532 if( g_mPos > 2 )
533 save_to_file( id )
534 else
535 ColorChat( id, RED, "^4[CUP]^1 Denied. Minimum markers are:^3 3" )
536 }
537 case 5:
538 {
539 if( faster_nc[ id ] )
540 {
541 set_user_noclip( id, 0 )
542 faster_nc[ id ] = false
543 }
544 else
545 {
546 set_user_noclip( id, 1 )
547 faster_nc[ id ] = true
548 }
549 }
550 }
551 cup_menu( id )
552 return PLUGIN_HANDLED
553}
554public save_to_file( id ) //save markers
555{
556 new file = fopen( filename, "w+" )
557
558 if( file )
559 {
560 for( new o = 1; o <= g_mPos; o++ )
561 {
562 fprintf( file, "%.01f %.01f %.01f^n", fOrigin[ o ][ 0 ], fOrigin[ o ][ 1 ], fOrigin[ o ][ 2 ] )
563 }
564 ColorChat( 0, BLUE, "^4[CUP]^1 Saved^3 %d markers^1 for this map.", g_mPos )
565 fclose( file )
566 }
567 else
568 {
569 ColorChat( 0, BLUE, "^4[CUP]^1 Not found file:^4 %s", filename )
570 }
571 return PLUGIN_HANDLED
572}
573public winner()
574{
575 new bestIS = get_best_player( 1 )
576 new name[ 32 ]; get_user_name( bestIS, name, 31 )
577 new Float:velocity[3];
578 entity_get_vector( bestIS, EV_VEC_velocity, velocity );
579
580 if( bestIS > 0 )
581 {
582 ColorChat( 0, BLUE, "^4[CUP]^1 Winner is:^3 %s%s^1> %.00f%% completed", name, velocity[2] !=0.0 ? " ^4[in air] ":" ", (( float( ( g_pBestTouch[ bestIS ] + 1 ) - ent[ 1 ] ) / ( float( g_mPos )) ) * 100 ) )
583 set_winner( bestIS )
584 }
585}
586public get_best_player( final ) //most important if markers are on that map
587{
588 new bestvalue = 1 //let it be first marker
589 new id
590 new Float:pOrigin[ 3 ], Float:markerOrigin[ 3 ]
591 new wanted_id = 0
592 new Float: best_distance, Float: distance
593 new Float: previousMarker[ 3 ]
594 new Float: nextMarker[ 3 ]
595 new Float: nextDiff
596
597 for( new i = 0; i <= g_pInCup; i++ )
598 {
599 if( final == 1 )
600 id = p_inDuel[ i ]
601 else
602 id = pWant_duel[ i ]
603
604 if( g_pBestTouch[ id ] >= bestvalue )
605 {
606 entity_get_vector( id, EV_VEC_origin, pOrigin )
607
608 if( g_pBestTouch[ id ] == ent[ g_mPos ] )
609 {
610 bestvalue = g_pBestTouch[ id ]
611 best_distance = distance
612 wanted_id = id
613 return wanted_id
614 }
615 else
616 {
617 entity_get_vector( ( g_pBestTouch[ id ] ), EV_VEC_origin, markerOrigin )
618 entity_get_vector( ( g_pBestTouch[ id ] + 1 ), EV_VEC_origin, nextMarker )
619 entity_get_vector( ( g_pBestTouch[ id ] - 1 ), EV_VEC_origin, previousMarker )
620 }
621
622 distance = get_distance_f( pOrigin, nextMarker )
623
624 if( g_pBestTouch[ id ] > bestvalue )
625 {
626 new Float:fallDist = floatabs( pOrigin[ 2 ] - markerOrigin[ 2 ] )
627
628 if( fallDist > 250.0 )
629 { //didnt fall too deep
630 nextDiff = floatabs( markerOrigin[ 2 ] - nextMarker[ 2 ] )
631
632 if( nextDiff < 150.0 )
633 {
634 if( floatabs( pOrigin[ 2 ] - nextMarker[ 2 ] ) < 150.0 )
635 {
636 bestvalue = g_pBestTouch[ id ]
637 best_distance = distance
638 wanted_id = id
639 //client_print( 0, print_console, "^1winner info^4 to next:^3 %.01f^4 to prev:^3 %.01f^4 Z:^1 %.01f", distance, prevMarker, fallDist )
640 }
641 else
642 {
643 ColorChat( 0, RED, " --- We think one player fall at the last second of cup ---" )
644 //client_print( 0, print_console, "*failer info: marker difference: %.01f - player/nextm: %.01f", floatabs( markerOrigin[ 2 ] - nextMarker[ 2 ] ), floatabs( pOrigin[ 2 ] - nextMarker[ 2 ] ) )
645 }
646 }
647 else
648 {
649 if( floatabs( pOrigin[ 2 ] - nextMarker[ 2 ] ) < 300.0 && pOrigin[ 2 ] > nextMarker[ 2 ] )
650 {
651 bestvalue = g_pBestTouch[ id ]
652 best_distance = distance
653 wanted_id = id
654 //client_print( 0, print_console, "^1***winner info^4 to next:^3 %.01f^4 to prev:^3 %.01f^4 Z:^1 %.01f", distance, prevMarker, fallDist )
655 }
656 else
657 {
658 ColorChat( 0, RED, " --- We think one player fall at the last second of cup ---" )
659 //client_print( 0, print_console, "^1failer info: marker difference: %.01f - player/nextm: %.01f", floatabs( markerOrigin[ 2 ] - nextMarker[ 2 ] ), floatabs( pOrigin[ 2 ] - nextMarker[ 2 ] ) )
660 }
661 }
662 }
663 else
664 {
665 bestvalue = g_pBestTouch[ id ]
666 best_distance = distance
667 wanted_id = id
668 //client_print( 0, print_console, "^1**winner info^4 to next:^3 %.01f^4 to prev:^3 %.01f^4 Z:^1 %.01f", distance, prevMarker, fallDist )
669 }
670 }
671 else if( distance < best_distance )
672 {
673 best_distance = distance
674 wanted_id = id
675 }
676 }
677
678 }
679 return wanted_id
680}
681public create_marker( id, check )
682{
683 new origin[ 3 ]
684
685 g_mPos++
686 ent[ g_mPos ] = create_entity( "info_target" )
687
688 if( check == 1 )
689 {
690 get_user_origin( id, origin, 3 )
691
692 fOrigin[ g_mPos ][ 0 ] = float( origin[ 0 ] )
693 fOrigin[ g_mPos ][ 1 ] = float( origin[ 1 ] )
694 fOrigin[ g_mPos ][ 2 ] = float( origin[ 2 ] )
695
696 fOrigin[ g_mPos ][ 2 ] +=70.0
697 }
698 else
699 {
700 fOrigin[ g_mPos ][ 0 ] = test_origin[ 0 ]
701 fOrigin[ g_mPos ][ 1 ] = test_origin[ 1 ]
702 fOrigin[ g_mPos ][ 2 ] = test_origin[ 2 ]
703 }
704 entity_set_origin( ent[ g_mPos ], fOrigin[ g_mPos ] );
705
706 entity_set_string( ent[ g_mPos ], EV_SZ_classname, "cup_marker" )
707 entity_set_model( ent[ g_mPos ], g_Model );
708
709 entity_set_int( ent[ g_mPos ], EV_INT_solid, 1 )
710
711 new Float:maxs[ 3 ] = { 50.0, 50.0, 20.0 }
712 new Float:mins[ 3 ] = { -50.0, -50.0, -20.0 }
713 entity_set_size( ent[ g_mPos ], mins, maxs )
714
715 if( !g_markerVis )
716 set_pev( ent[ g_mPos ], pev_rendermode, kRenderTransAlpha)
717}
718public remove_marker( id, all )
719{
720 if( !all )
721 {
722 remove_entity( ent[ g_mPos-- ] )
723 }
724 else
725 {
726 remove_entity_name( "cup_marker" )
727 g_mPos = 0
728 }
729}
730
731public pfn_touch( ent1, id )
732{
733 new classname[ 32 ], name[ 32 ]
734 entity_get_string( ent1, EV_SZ_classname, classname, 31 )
735
736 if( equal( classname, "cup_marker" ) )
737 {
738 if ( !(1 <= id <= get_maxplayers() && pWant_duel[ id ]) || !d_started ) //check if only player entity touch //klippy
739 return PLUGIN_HANDLED
740
741 get_user_name( id, name, charsmax( name ) )
742 #if defined SHOW_SC
743 if( g_playerTouched[ id ] > 2 && ( ( ent1 - g_pBestTouch[ id ] ) >= 3 ) && d_started && !teleporting_p[ id ] )
744 {
745 set_dhudmessage( 255, 85, 0, 0.03, 0.23, 0, 2.5, 2.5 )
746 show_dhudmessage( 0, "ALERT! %s did a sc!", name )
747 }
748 #endif
749 g_pBestTouch[ id ] = ent1
750 if( !g_fixCheck[ id ][ ent1 ] )
751 {
752 g_playerTouched[ id ]++
753 if( g_playerTouched[ id ] > 1 )
754 {
755 for( new o = 1; o < g_playerTouched[ id ]; o++ )
756 {
757 if( ( ent1 - o ) > ( ent1 - g_playerTouched[ id ] ) )
758 {
759 g_fixCheck[ id ][ ent1-o ] = false
760 }
761 }
762 }
763 if( ent[ g_mPos ] == ent1 && !teleporting_p[ id ] )
764 {
765 client_print( 0, print_console, "The winner touched last marker: %d", ent1 )
766
767 get_players( players, playerNum, "a" )
768 for( new i = 0; i < playerNum; i++ )
769 {
770 if( pWant_duel[ players[ i ] ] )
771 {
772 remove_task( players[ i ] )
773 finish_Cup( players[ i ] )
774 }
775 }
776 }
777
778 }
779 g_fixCheck[ id ][ ent1 ] = true
780 }
781 return PLUGIN_CONTINUE
782}
783public duel_open_pre( id )
784{
785 if( get_user_team( id ) != 2 )
786 {
787 ColorChat( id, BLUE, "^4[CUP]^1 You must be in^3 CT" )
788 return PLUGIN_HANDLED
789 }
790 if( allWant_duel )
791 {
792 ColorChat( id, GREY, "^4[CUP]^1 It's already started, wait some moments." )
793 return PLUGIN_HANDLED
794 }
795 new g_TimeCup_text[ 150 ]; formatex( g_TimeCup_text, 149, "Time of the battle:\y %d minutes^n%s",
796 g_TimeCup, g_mPos > 0 ? "^t^t^t^t^t^t^t^t\r- With markers \d/cup15 gets updated^n" :"^t^t^t^t^t^t^t^t\rWithout markers \djust 4 fun, no winner^n" )
797 new pro_or_noob[ 150 ]; formatex( pro_or_noob, 149, "\wWith CP/TP? %s", g_InPro ? "\d No, like Pro15^n":"\rYes\d, like Noob15^n" )
798
799 new menu = menu_create( "\yKZ Autocup!^n\dVersion: 2.5", "cupHandled" )
800
801 menu_additem( menu, g_TimeCup_text )
802 menu_additem( menu, pro_or_noob )
803 menu_additem( menu, "\yStart your cup!" )
804
805 menu_display( id, menu, 0 )
806
807 return PLUGIN_CONTINUE
808}
809public cupHandled( id, menu, item )
810{
811 if( d_started || allWant_duel )
812 {
813 ColorChat( id, BLUE, "^4[CUP]^1 Sorry, cup is already started." )
814 menu_destroy( menu )
815 return PLUGIN_HANDLED
816 }
817
818 switch( item )
819 {
820 case 0:
821 {
822 switch( g_TimeCup )
823 {
824 case 1:
825 {
826 g_TimeCup += 1
827 duel_open_pre( id )
828 }
829 case 2:
830 {
831 g_TimeCup += 1
832 duel_open_pre( id )
833 }
834 case 3:
835 {
836 g_TimeCup = 5
837 duel_open_pre( id )
838 }
839 case 5:
840 {
841 g_TimeCup = 7
842 duel_open_pre( id )
843 }
844 case 7:
845 {
846 g_TimeCup = 1
847 duel_open_pre( id )
848 }
849 }
850 }
851 case 1:
852 {
853 g_InPro = !g_InPro
854 duel_open_pre( id )
855 }
856 case 2:
857 {
858 duel_open( id )
859 }
860 }
861 menu_destroy( menu )
862 return PLUGIN_HANDLED
863}
864public duel_open( id )
865{
866 get_user_name( id, g_StartedName, charsmax( g_StartedName ) )
867
868 pWant_duel[ id ] = true
869 g_pInCup++
870
871 allWant_duel = true
872 fPrepareTime = get_gametime()
873
874 ColorChat( 0, BLUE, "^4[CUP]^1 Cup started by:^4 %s^1 %dmin.^4 15sec^1 waiting for others to join...", g_StartedName, g_TimeCup )
875
876 set_hudmessage( 255, 85, 0, 0.65, 0.2, 0, 3.0, 9.0 )
877 ShowSyncHudMsg( 0, g_hudInfo, "%s started a cup!^nsay /joincup - to join and teach him a leasson!", g_StartedName )
878
879 set_task( 15.0, "kraj_open", id )
880
881
882 get_players( players, playerNum, "a" )
883 for( new i=0; i < playerNum; i++ )
884 {
885 SendCmd_1( players[ i ], "spk events/task_complete" )
886 if( g_InPro )
887 SendCmd_1( players[ i ], "spk ^"_period _period _period _period without _period checkpoint^"" )
888 else
889 SendCmd_1( players[ i ], "spk ^"_period _period _period _period with _period checkpoint^"" )
890 count_Start( players[ i ] )
891 }
892}
893public count_Start( id )
894{
895 if( !is_user_connected( id ) )
896 return PLUGIN_HANDLED
897
898 new poruka[55]
899 format( poruka, charsmax( poruka ), "%s's CUP, say /joincup; Remaining: %.01f", g_StartedName, stime[ id ] )
900
901 static msgStatusText=0;
902 if(!msgStatusText)
903 msgStatusText = get_user_msgid("StatusText");
904
905 stime[ id ] -= 0.1
906 if( stime[ id ] >= 0 )
907 {
908 message_begin(MSG_ONE_UNRELIABLE, msgStatusText, _, id);
909 write_byte(0);
910 write_string(poruka);
911 message_end();
912 set_task( 0.1, "count_Start", id )
913 }
914 else
915 {
916 message_begin(MSG_ONE_UNRELIABLE, msgStatusText, _, id);
917 write_byte(0);
918 write_string("");
919 message_end();
920 stime[ id ] = 15.0
921 }
922 return PLUGIN_CONTINUE
923}
924
925public join_duel( id )
926{
927 if( get_user_team( id ) != 2 )
928 {
929 ColorChat( id, BLUE, "^4[CUP]^1 You must be in^3 CT" )
930 return PLUGIN_HANDLED
931 }
932 new name[ 32 ], Float: get_timing, Float: pred_polazak
933 get_user_name( id, name, charsmax( name ) )
934
935 if( pWant_duel[ id ] )
936 return PLUGIN_HANDLED
937
938 get_timing = get_gametime() - fPrepareTime
939 if( get_timing >= 15.0 && d_started)
940 {
941 ColorChat( id, GREY, "^4[CUP]^1 Someone is already playing,^3 wait or go /spec ;)" )
942 }
943 else
944 {
945 pred_polazak = 15.0 - get_timing
946 set_task( pred_polazak, "pocetak_CUPa", id )
947 }
948
949 if( allWant_duel && !d_started )
950 {
951 pWant_duel[ id ] = true
952 g_pInCup++
953 ColorChat( 0, BLUE, "^4[CUP]^3 %s^1 joined! Cup name:^4 %s", name, g_StartedName )
954 }
955 if( !allWant_duel )
956 {
957 ColorChat( id, BLUE, "^4[CUP]^1 No one started, go /startcup." )
958 }
959 return PLUGIN_HANDLED
960}
961public kraj_open( id )
962{
963 if( g_pInCup <= 1 )
964 {
965 ColorChat( id, BLUE, "^4[CUP]^1 No enought players, sorry." )
966 real_end( id )
967 SendCmd_1( id, "speak events/tutor_msg" )
968 }
969 else
970 {
971 set_dhudmessage( 255, 85, 0, -1.0, 0.45, 0, 2.5, 2.5 )
972 show_dhudmessage( id, "Players: %d^n^nStarts in:", g_pInCup )
973 pocetak_CUPa( id )
974 }
975}
976public pocetak_CUPa( id )
977{
978 if( pWant_duel[ id ] )
979 {
980 SendCmd_1( id, "say /start" )
981 if( !g_InPro )
982 {
983 drop_to_floor( id )
984 SendCmd_1( id, "say /cp" )
985 }
986 set_task( 0.1, "frozen", id )
987 //ColorChat( id, BLUE, "^4[CUP]^1 GL HF BRO" )
988
989 //progress bar
990 message_begin( MSG_ONE , g_msgBarTime , {0,0,0} , id )
991 write_short( 5 )
992 message_end()
993
994 set_user_rendering(id, kRenderFxGlowShell, r, g, b, kRenderNormal, 8)
995 d_started = true
996 set_task( 5.0, "start_CUP", id )
997
998 find_origin = false
999 }
1000}
1001public frozen( id )
1002{
1003 fm_set_user_frozen( id, 1 )
1004
1005 ScreenFade( id )
1006}
1007
1008public start_CUP( id )
1009{
1010 new Float: originp[ 3 ]
1011 entity_get_vector( id, EV_VEC_origin, originp )
1012 g_timetime[ id ] = 60*g_TimeCup
1013 originp[2]+=40.0
1014 entity_set_origin( id, originp )
1015 timer( id )
1016 fm_set_user_frozen( id, 0 )
1017 set_pev( id, pev_velocity, Float:{0.0, 0.0, 0.0} );
1018 engfunc( EngFunc_SetSize, id, {-16.0, -16.0, -18.0 }, { 16.0, 16.0, 32.0 } );
1019 ColorChat( id, BLUE, "^4[CUP]^1 Started ! GL & HF !^4 %dmin^1 remainig", g_TimeCup )
1020 set_task( 60.0*g_TimeCup, "finish_Cup", id )
1021}
1022public exitCup( id )
1023{
1024 if( pWant_duel[ id ] )
1025 {
1026 new name[ 32 ]; get_user_name( id, name, charsmax( name ) )
1027 if( d_started )
1028 {
1029 g_pInCup -= 1
1030 pWant_duel[ id ] = false
1031
1032 remove_task( id )
1033 if( g_pInCup <= 1 )
1034 {
1035 real_end( id )
1036 ColorChat( 0, GREY, "^4[CUP]^1 All players left the cup, you can^4 /startcup^1 now" )
1037 }
1038 else
1039 ColorChat( 0, RED, "^4[CUP]^1 One player left the cup:^3 %s", name )
1040 set_user_rendering( id )
1041 }
1042 else
1043 {
1044 pWant_duel[ id ] = false
1045 remove_task( id )
1046 }
1047 }
1048 else
1049 {
1050 client_print( id, print_chat, "[CUP] From where to exit lol ?" )
1051 }
1052 return PLUGIN_HANDLED
1053}
1054
1055public finish_Cup( id )
1056{
1057 teleporting_p[ id ] = true
1058 set_user_rendering( id ) //reset glow
1059 g_pNumber = g_pInCup
1060 fm_set_user_frozen( id, 1 )
1061 ScreenFade( id )
1062 remove_task( id )
1063
1064 if( !find_origin )//must be executed once per cup
1065 {
1066 Find_origins()
1067 find_origin = true
1068
1069 if( g_mPos > 2 )
1070 winner()
1071 }
1072 SendCmd_1( id, "say /start" )
1073
1074 set_task( 4.0, "teleport_origin", id + TASK_TELEPORT )
1075
1076 set_task( 4.0*g_pNumber+4.0, "real_end", id ) //real finish
1077}
1078public Find_origins()
1079{
1080 new id, x=0
1081 get_players( players, playerNum, "a" )
1082
1083 for( new i = 0; i < playerNum; i++ )
1084 {
1085 id = players[ i ]
1086 if( pWant_duel[ id ] )
1087 {
1088 entity_get_vector( id, EV_VEC_origin, origins[ id ] )
1089
1090 get_user_name( id, spec_nick[ id ], charsmax( spec_nick[] ) )
1091 p_inDuel[ x++ ] = id //thanks kushfield
1092
1093 }
1094 }
1095}
1096public teleport_origin( id )
1097{
1098 id = id - TASK_TELEPORT;
1099
1100 engfunc( EngFunc_SetOrigin, id, origins[ p_inDuel[ currentPlayer[ id ]]] )
1101
1102 set_dhudmessage( 255, 85, 0, -1.0, 0.4, 0, 2.5, 2.5 )
1103 show_dhudmessage( id, "Teleported to: %s", spec_nick[ p_inDuel[ currentPlayer[ id ]]] )
1104 currentPlayer[ id ]++
1105
1106 if( g_pInCup > currentPlayer[ id ] )
1107 set_task( 4.0, "teleport_origin", id+ TASK_TELEPORT )
1108}
1109public real_end( id )
1110{
1111 set_dhudmessage( 255, 85, 0, -1.0, 0.3, 0, 3.0, 3.0)
1112 show_dhudmessage( id, "THE END! Players: %d^nCheck /cup15 bro !", g_pNumber )
1113 ColorChat( id, BLUE, "^4[CUP]^1 It's finished^1 GG ! For another one, go ^4/startcup^1 !" )
1114 d_started = false
1115 g_pInCup = 0
1116 //g_pNumber = 0
1117 pWant_duel[ id ] = false
1118 allWant_duel = false
1119 g_StartedName = ""
1120 fm_set_user_frozen( id, 0 )
1121 remove_task( id )
1122 teleporting_p[ id ] = false
1123 client_cmd( id, "say /start" )
1124 g_TimeCup = 1
1125 find_origin = false
1126 currentPlayer[ id ] = 0
1127 g_InPro = true
1128
1129 g_playerTouched[ id ] = 0
1130 g_pBestTouch[ id ] = 0
1131 for( new o = 1; o <= g_mPos; o++ )
1132 {
1133 g_fixCheck[ id ][ ent[ g_mPos - o ] ] = false
1134 }
1135 g_fixCheck[ id ][ ent[ g_mPos ] ] = false
1136}
1137stock fm_set_user_frozen(client, frozen)
1138{
1139 if( !is_user_alive(client) ) return 0;
1140
1141 new flags = pev(client, pev_flags);
1142 if( frozen && !(flags & FL_FROZEN) )
1143 {
1144 set_pev(client, pev_flags, (flags | FL_FROZEN))
1145
1146 }
1147 else if( !frozen && (flags & FL_FROZEN) )
1148 {
1149 set_pev(client, pev_flags, (flags & ~FL_FROZEN));
1150 }
1151
1152 return 1;
1153}
1154
1155public ScreenFade(id )
1156{
1157 message_begin(MSG_ONE, get_user_msgid("ScreenFade"), {0,0,0}, id)
1158 write_short((1<<10)*4)
1159 write_short((1<<10)*15)
1160 write_short(0x0000)
1161 write_byte(150)
1162 write_byte(100)
1163 write_byte(5)
1164 write_byte(90)
1165 message_end()
1166}
1167stock SendCmd_1( id , text[] ) //cuz filtercmd 1
1168{
1169 message_begin( MSG_ONE, 51, _, id )
1170 write_byte( strlen(text) + 2 )
1171 write_byte( 10 )
1172 write_string( text )
1173 message_end()
1174}