· 9 years ago · Dec 16, 2016, 10:16 AM
1public PlVers:__version =
2{
3 version = 5,
4 filevers = "1.7.3-dev+5275",
5 date = "03/08/2016",
6 time = "21:05:08"
7};
8new Float:NULL_VECTOR[3];
9new String:NULL_STRING[4];
10public Extension:__ext_core =
11{
12 name = "Core",
13 file = "core",
14 autoload = 0,
15 required = 0,
16};
17new MaxClients;
18public Extension:__ext_sdktools =
19{
20 name = "SDKTools",
21 file = "sdktools.ext",
22 autoload = 1,
23 required = 1,
24};
25public Extension:__ext_cstrike =
26{
27 name = "cstrike",
28 file = "games/game.cstrike.ext",
29 autoload = 0,
30 required = 1,
31};
32public Extension:__ext_regex =
33{
34 name = "Regex Extension",
35 file = "regex.ext",
36 autoload = 1,
37 required = 1,
38};
39new Handle:CTrie;
40new CTeamColors[1][3] =
41{
42 {
43 13421772, 5077314, 16728128
44 }
45};
46new String:CTag[17][0];
47new String:CTagCode[17][16] =
48{
49 "\x01",
50 "\x02",
51 "\x04",
52 "\x03",
53 "\x03",
54 "\x03",
55 "\x05",
56 "",
57 "\x07",
58 "\x03",
59 "\x08",
60 " ",
61 "\n",
62 "",
63 "",
64 "",
65 ""
66};
67new bool:CTagReqSayText2[17] =
68{
69 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70};
71new bool:CEventIsHooked;
72new bool:CSkipList[66];
73new bool:CProfile_Colors[17] =
74{
75 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
76};
77new CProfile_TeamIndex[15] =
78{
79 -1, ...
80};
81new bool:CProfile_SayText2;
82new Handle:sm_show_activity = 1635151433;
83new localIPRanges[4] =
84{
85 1819044171, 1919248712, 1751347809, 121
86};
87new String:chatColorNames[12][0];
88new String:chatColorTags[12][16] =
89{
90 "normal",
91 "orange",
92 "red",
93 "redblue",
94 "blue",
95 "bluered",
96 "team",
97 "lightgreen",
98 "gray",
99 "green",
100 "olivegreen",
101 "black"
102};
103new chatColorInfo[12][4] =
104{
105 {
106 1, -1, 1, -3
107 },
108 {
109 1, 0, 1, -3
110 },
111 {
112 3, 9, 1, 2
113 },
114 {
115 3, 4, 1, 2
116 },
117 {
118 3, 9, 1, 3
119 },
120 {
121 3, 2, 1, 3
122 },
123 {
124 3, 9, 1, -2
125 },
126 {
127 3, 9, 1, 0
128 },
129 {
130 3, 9, 1, -1
131 },
132 {
133 4, 0, 1, -3
134 },
135 {
136 5, 9, 1, -3
137 },
138 {
139 6, 9, 1, -3
140 }
141};
142new bool:checkTeamPlay;
143new Handle:mp_teamplay;
144new bool:isSayText2_supported = 1;
145new chatSubject = -2;
146new Float:getPlayersInRadius_distances[66];
147new printToChat_excludeclient;
148new String:_smlib_empty_twodimstring_array[1][16];
149new base64_cFillChar = 3308130;
150new base64_decodeTable[256] =
151{
152 3308130, 1886221434, 0, 12079, 47, 1162690887, 0, 1162690887, 0, 46, 11822, 623866661, 115, 42, 46, 46, 11822, 623866661, 115, 25202, 1162690887, 0, 25207, 1095124292, 1599360085, 1414091351, 1095786309, 18516, 11822, 46, 623866661, 115, 623866661, 115, 0, 807760677, 624583729, 979644976, 0, 807760677, 3826737, 807760677, 1714630198, 0, 807760677, 1714630196, 0, 807760677, 25650, 807760677, 25649, 1701669236, 114, 1701669236, 1868770674, 1932420466, 30829, 7404, 7412, 1, 1701669204, 1951620978, 7631457, 1701669204, 1951620978, 28783, 1701669204, 1699897202, 1918989427, 116, 1701669204, 1632657266, 6648693, 1701669204, 1699897202, 1701672307, 0, 1701669204, 1699176306, 1936015988, 1970229876, 25710, 1701669204, 1699176306, 1768702836, 1416916581, 1919249769, 0, 1701669204, 1766219634, 1752394094, 1853189970, 100, 1701669204, 1866882930, 1382376306, 1634692197, 1936015972, 1970229876, 1631806574, 6645859, 1701669204, 1699176306, 1953453172, 1632791649, 27502, 1701669204, 1699176306, 1920287604, 1953391986, 1802395986, 0, 1701669236, 1869360498, 1852401511, 103, 1701669236, 1869360498, 1852401511, 1836265063, 120, 7648, 7664, 1, 1701669204, 1699176306, 1735347316, 1702257996, 108, 1701669204, 1867276146, 103, 1701669204, 1867276146, 1920091495, 29295, 1701669204, 1867276146, 1918981991, 1735289198, 0, 1701669204, 1867276146, 1718503783, 111, 1701669204, 1867276146, 1650803815, 26485, 1701669204, 1867276146, 1650803815, 3303285, 1701669236, 1870081394, 1919183986, 1919902565, 100, 1701669236, 1870081394, 1919183986, 1919902565, 1836265060, 120, 7812, 7832, 1, 1701669204, 1866882930, 1382376306, 1634692197, 1919899492, 1699898476, 1685221219, 1751343427, 101, 1701669204, 1866882930, 1382376306, 1634692197, 1852785252, 1868002165, 1382313074, 1919902565, 1667318628, 25960, 1701669236, 114, 1701669236, 1634545010, 1852799600, 1932424037, 30829, 7944, 7952, 0, 1701669204, 1800626034, 1699639401, 1968141432, 1953853556, 0, 1701669204, 1934188402, 1886680399, 1816294517, 1701536623, 100, 1701669204, 1699176306, 1634488436, 1400006009, 1702125940, 0, 1701669204, 1699176306, 1634488436, 1400006009, 1701273972, 0, 1701669204, 1699962738, 1634488436, 1400006009, 1701273972, 0, 1701669204, 1700028274, 1869636972, 1816360050, 1953391977, 1951625044, 6645601, 1701669204, 1699176306, 1635013492, 1866687847, 7630453, 1701669204, 1699176306, 1852785268, 1868198773, 7562606, 1701669204, 1632460658, 28265, 1701669204, 1750359922, 1231385189, 1635013491, 1850045554, 1852791396, 101, 1701669204, 1750359922, 1231385189
153};
154new String:base64_mime_chars[4] = "bz2";
155new String:base64_sTable[68] = "bz2";
156new String:base64_url_chars[4] = "bz2";
157new printToTop_excludeclient = 3308130;
158public SharedPlugin:__pl_timer =
159{
160 name = "timer",
161 file = "timer-core.smx",
162 required = 1,
163};
164public SharedPlugin:__pl_timer_logging =
165{
166 name = "timer-logging",
167 file = "timer-logging.smx",
168 required = 1,
169};
170public SharedPlugin:__pl_timer_worldrecord =
171{
172 name = "timer-worldrecord",
173 file = "timer-worldrecord.smx",
174 required = 1,
175};
176public SharedPlugin:__pl_timer_mapzones =
177{
178 name = "timer",
179 file = "timer-mapzones.smx",
180 required = 0,
181};
182public SharedPlugin:__pl_timer_ghost =
183{
184 name = "timer-ghost",
185 file = "timer-ghost.smx",
186 required = 0,
187};
188public SharedPlugin:__pl_timer_race =
189{
190 name = "timer-race",
191 file = "timer-race.smx",
192 required = 0,
193};
194public SharedPlugin:__pl_timer_physics =
195{
196 name = "timer-physics",
197 file = "timer-physics.smx",
198 required = 0,
199};
200public SharedPlugin:__pl_timer_ghost_trikz =
201{
202 name = "timer-ghost-trikz",
203 file = "timer-ghost_trikz.smx",
204 required = 0,
205};
206new Handle:g_hSQL;
207new String:g_sCurrentMap[32];
208new g_iReconnectCounter;
209new g_timers[66][36];
210new gi_TotalRecords[32];
211new gi_StageTotalRecords[32][32];
212new gi_BonusTotalRecords[32][32];
213new g_difficultyCount;
214new Float:g_fOldAngle[66];
215new Handle:g_hTimerStartedForward;
216new Handle:g_hStageTimerStartedForward;
217new Handle:g_hTimerStoppedForward;
218new Handle:g_hTimerRestartForward;
219new Handle:g_hTimerBonusRestartForward;
220new Handle:g_hTimerPauseForward;
221new Handle:g_hTimerResumeForward;
222new Handle:g_hFinishRoundForward;
223new Handle:g_hFinishBonusRoundForward;
224new Handle:g_hFinishStageForward;
225new Handle:g_hCvarRestartEnabled;
226new Handle:g_hCvarStopEnabled;
227new Handle:g_hCvarPauseResumeEnabled;
228new Handle:g_hCvarShowJumps;
229new Handle:g_hCvarShowStrafes;
230new Handle:g_hCvarShowFlashbangs;
231new Handle:g_hCvarFreezeOnPause;
232new bool:g_bRestartEnabled = 1;
233new bool:g_bStopEnabled = 1;
234new bool:g_bPauseResumeEnabled = 1;
235new bool:g_bShowJumps = 1;
236new bool:g_bShowFlashbangs;
237new bool:g_bShowStrafes = 1;
238new bool:g_bFreezeOnPause;
239new bool:g_bTimerMapZones;
240new bool:g_bTimerPhysics;
241new bool:g_bTimerRace;
242new bool:g_bTimerGhost;
243new bool:g_bTrikz;
244public Plugin:myinfo =
245{
246 name = "[Timer] Core",
247 description = "Core component for [Timer]",
248 author = "alongub | Glite | Ofir | root",
249 version = "1.1.0",
250 url = "https://github.com/alongubkin/timer"
251};
252new g_LastPlayerButtons[66];
253public __ext_core_SetNTVOptional()
254{
255 MarkNativeAsOptional("GetFeatureStatus");
256 MarkNativeAsOptional("RequireFeature");
257 MarkNativeAsOptional("AddCommandListener");
258 MarkNativeAsOptional("RemoveCommandListener");
259 MarkNativeAsOptional("BfWriteBool");
260 MarkNativeAsOptional("BfWriteByte");
261 MarkNativeAsOptional("BfWriteChar");
262 MarkNativeAsOptional("BfWriteShort");
263 MarkNativeAsOptional("BfWriteWord");
264 MarkNativeAsOptional("BfWriteNum");
265 MarkNativeAsOptional("BfWriteFloat");
266 MarkNativeAsOptional("BfWriteString");
267 MarkNativeAsOptional("BfWriteEntity");
268 MarkNativeAsOptional("BfWriteAngle");
269 MarkNativeAsOptional("BfWriteCoord");
270 MarkNativeAsOptional("BfWriteVecCoord");
271 MarkNativeAsOptional("BfWriteVecNormal");
272 MarkNativeAsOptional("BfWriteAngles");
273 MarkNativeAsOptional("BfReadBool");
274 MarkNativeAsOptional("BfReadByte");
275 MarkNativeAsOptional("BfReadChar");
276 MarkNativeAsOptional("BfReadShort");
277 MarkNativeAsOptional("BfReadWord");
278 MarkNativeAsOptional("BfReadNum");
279 MarkNativeAsOptional("BfReadFloat");
280 MarkNativeAsOptional("BfReadString");
281 MarkNativeAsOptional("BfReadEntity");
282 MarkNativeAsOptional("BfReadAngle");
283 MarkNativeAsOptional("BfReadCoord");
284 MarkNativeAsOptional("BfReadVecCoord");
285 MarkNativeAsOptional("BfReadVecNormal");
286 MarkNativeAsOptional("BfReadAngles");
287 MarkNativeAsOptional("BfGetNumBytesLeft");
288 MarkNativeAsOptional("BfWrite.WriteBool");
289 MarkNativeAsOptional("BfWrite.WriteByte");
290 MarkNativeAsOptional("BfWrite.WriteChar");
291 MarkNativeAsOptional("BfWrite.WriteShort");
292 MarkNativeAsOptional("BfWrite.WriteWord");
293 MarkNativeAsOptional("BfWrite.WriteNum");
294 MarkNativeAsOptional("BfWrite.WriteFloat");
295 MarkNativeAsOptional("BfWrite.WriteString");
296 MarkNativeAsOptional("BfWrite.WriteEntity");
297 MarkNativeAsOptional("BfWrite.WriteAngle");
298 MarkNativeAsOptional("BfWrite.WriteCoord");
299 MarkNativeAsOptional("BfWrite.WriteVecCoord");
300 MarkNativeAsOptional("BfWrite.WriteVecNormal");
301 MarkNativeAsOptional("BfWrite.WriteAngles");
302 MarkNativeAsOptional("BfRead.ReadBool");
303 MarkNativeAsOptional("BfRead.ReadByte");
304 MarkNativeAsOptional("BfRead.ReadChar");
305 MarkNativeAsOptional("BfRead.ReadShort");
306 MarkNativeAsOptional("BfRead.ReadWord");
307 MarkNativeAsOptional("BfRead.ReadNum");
308 MarkNativeAsOptional("BfRead.ReadFloat");
309 MarkNativeAsOptional("BfRead.ReadString");
310 MarkNativeAsOptional("BfRead.ReadEntity");
311 MarkNativeAsOptional("BfRead.ReadAngle");
312 MarkNativeAsOptional("BfRead.ReadCoord");
313 MarkNativeAsOptional("BfRead.ReadVecCoord");
314 MarkNativeAsOptional("BfRead.ReadVecNormal");
315 MarkNativeAsOptional("BfRead.ReadAngles");
316 MarkNativeAsOptional("BfRead.GetNumBytesLeft");
317 MarkNativeAsOptional("PbReadInt");
318 MarkNativeAsOptional("PbReadFloat");
319 MarkNativeAsOptional("PbReadBool");
320 MarkNativeAsOptional("PbReadString");
321 MarkNativeAsOptional("PbReadColor");
322 MarkNativeAsOptional("PbReadAngle");
323 MarkNativeAsOptional("PbReadVector");
324 MarkNativeAsOptional("PbReadVector2D");
325 MarkNativeAsOptional("PbGetRepeatedFieldCount");
326 MarkNativeAsOptional("PbSetInt");
327 MarkNativeAsOptional("PbSetFloat");
328 MarkNativeAsOptional("PbSetBool");
329 MarkNativeAsOptional("PbSetString");
330 MarkNativeAsOptional("PbSetColor");
331 MarkNativeAsOptional("PbSetAngle");
332 MarkNativeAsOptional("PbSetVector");
333 MarkNativeAsOptional("PbSetVector2D");
334 MarkNativeAsOptional("PbAddInt");
335 MarkNativeAsOptional("PbAddFloat");
336 MarkNativeAsOptional("PbAddBool");
337 MarkNativeAsOptional("PbAddString");
338 MarkNativeAsOptional("PbAddColor");
339 MarkNativeAsOptional("PbAddAngle");
340 MarkNativeAsOptional("PbAddVector");
341 MarkNativeAsOptional("PbAddVector2D");
342 MarkNativeAsOptional("PbRemoveRepeatedFieldValue");
343 MarkNativeAsOptional("PbReadMessage");
344 MarkNativeAsOptional("PbReadRepeatedMessage");
345 MarkNativeAsOptional("PbAddMessage");
346 MarkNativeAsOptional("Protobuf.ReadInt");
347 MarkNativeAsOptional("Protobuf.ReadFloat");
348 MarkNativeAsOptional("Protobuf.ReadBool");
349 MarkNativeAsOptional("Protobuf.ReadString");
350 MarkNativeAsOptional("Protobuf.ReadColor");
351 MarkNativeAsOptional("Protobuf.ReadAngle");
352 MarkNativeAsOptional("Protobuf.ReadVector");
353 MarkNativeAsOptional("Protobuf.ReadVector2D");
354 MarkNativeAsOptional("Protobuf.GetRepeatedFieldCount");
355 MarkNativeAsOptional("Protobuf.SetInt");
356 MarkNativeAsOptional("Protobuf.SetFloat");
357 MarkNativeAsOptional("Protobuf.SetBool");
358 MarkNativeAsOptional("Protobuf.SetString");
359 MarkNativeAsOptional("Protobuf.SetColor");
360 MarkNativeAsOptional("Protobuf.SetAngle");
361 MarkNativeAsOptional("Protobuf.SetVector");
362 MarkNativeAsOptional("Protobuf.SetVector2D");
363 MarkNativeAsOptional("Protobuf.AddInt");
364 MarkNativeAsOptional("Protobuf.AddFloat");
365 MarkNativeAsOptional("Protobuf.AddBool");
366 MarkNativeAsOptional("Protobuf.AddString");
367 MarkNativeAsOptional("Protobuf.AddColor");
368 MarkNativeAsOptional("Protobuf.AddAngle");
369 MarkNativeAsOptional("Protobuf.AddVector");
370 MarkNativeAsOptional("Protobuf.AddVector2D");
371 MarkNativeAsOptional("Protobuf.RemoveRepeatedFieldValue");
372 MarkNativeAsOptional("Protobuf.ReadMessage");
373 MarkNativeAsOptional("Protobuf.ReadRepeatedMessage");
374 MarkNativeAsOptional("Protobuf.AddMessage");
375 VerifyCoreVersion();
376 return 0;
377}
378
379Float:operator/(Float:,_:)(Float:oper1, oper2)
380{
381 return oper1 / float(oper2);
382}
383
384Float:operator/(_:,Float:)(oper1, Float:oper2)
385{
386 return float(oper1) / oper2;
387}
388
389Float:operator+(Float:,_:)(Float:oper1, oper2)
390{
391 return oper1 + float(oper2);
392}
393
394Float:operator-(Float:,_:)(Float:oper1, oper2)
395{
396 return oper1 - float(oper2);
397}
398
399bool:operator>(Float:,_:)(Float:oper1, oper2)
400{
401 return oper1 > float(oper2);
402}
403
404bool:operator>(_:,Float:)(oper1, Float:oper2)
405{
406 return float(oper1) > oper2;
407}
408
409bool:operator<(Float:,_:)(Float:oper1, oper2)
410{
411 return oper1 < float(oper2);
412}
413
414bool:StrEqual(String:str1[], String:str2[], bool:caseSensitive)
415{
416 return strcmp(str1, str2, caseSensitive) == 0;
417}
418
419CharToUpper(chr)
420{
421 if (IsCharLower(chr))
422 {
423 return chr & -33;
424 }
425 return chr;
426}
427
428CharToLower(chr)
429{
430 if (IsCharUpper(chr))
431 {
432 return chr | 32;
433 }
434 return chr;
435}
436
437FindCharInString(String:str[], String:c, bool:reverse)
438{
439 new len = strlen(str);
440 if (!reverse)
441 {
442 new i;
443 while (i < len)
444 {
445 if (c == str[i])
446 {
447 return i;
448 }
449 i++;
450 }
451 }
452 else
453 {
454 new i = len + -1;
455 while (0 <= i)
456 {
457 if (c == str[i])
458 {
459 return i;
460 }
461 i--;
462 }
463 }
464 return -1;
465}
466
467StrCat(String:buffer[], maxlength, String:source[])
468{
469 new len = strlen(buffer);
470 if (len >= maxlength)
471 {
472 return 0;
473 }
474 return Format(buffer[len], maxlength - len, "%s", source);
475}
476
477Handle:StartMessageOne(String:msgname[], client, flags)
478{
479 new players[1];
480 players[0] = client;
481 return StartMessage(msgname, players, 1, flags);
482}
483
484MoveType:GetEntityMoveType(entity)
485{
486 static bool:gotconfig;
487 static String:datamap[32];
488 if (!gotconfig)
489 {
490 new Handle:gc = LoadGameConfigFile("core.games");
491 new bool:exists = GameConfGetKeyValue(gc, "m_MoveType", datamap, 32);
492 CloseHandle(gc);
493 if (!exists)
494 {
495 strcopy(datamap, 32, "m_MoveType");
496 }
497 gotconfig = true;
498 }
499 return GetEntProp(entity, PropType:1, datamap, 4, 0);
500}
501
502SetEntityMoveType(entity, MoveType:mt)
503{
504 static bool:gotconfig;
505 static String:datamap[32];
506 if (!gotconfig)
507 {
508 new Handle:gc = LoadGameConfigFile("core.games");
509 new bool:exists = GameConfGetKeyValue(gc, "m_MoveType", datamap, 32);
510 CloseHandle(gc);
511 if (!exists)
512 {
513 strcopy(datamap, 32, "m_MoveType");
514 }
515 gotconfig = true;
516 }
517 SetEntProp(entity, PropType:1, datamap, mt, 4, 0);
518 return 0;
519}
520
521Float:GetEntityGravity(entity)
522{
523 static bool:gotconfig;
524 static String:datamap[32];
525 if (!gotconfig)
526 {
527 new Handle:gc = LoadGameConfigFile("core.games");
528 new bool:exists = GameConfGetKeyValue(gc, "m_flGravity", datamap, 32);
529 CloseHandle(gc);
530 if (!exists)
531 {
532 strcopy(datamap, 32, "m_flGravity");
533 }
534 gotconfig = true;
535 }
536 return GetEntPropFloat(entity, PropType:1, datamap, 0);
537}
538
539SetEntityGravity(entity, Float:amount)
540{
541 static bool:gotconfig;
542 static String:datamap[32];
543 if (!gotconfig)
544 {
545 new Handle:gc = LoadGameConfigFile("core.games");
546 new bool:exists = GameConfGetKeyValue(gc, "m_flGravity", datamap, 32);
547 CloseHandle(gc);
548 if (!exists)
549 {
550 strcopy(datamap, 32, "m_flGravity");
551 }
552 gotconfig = true;
553 }
554 SetEntPropFloat(entity, PropType:1, datamap, amount, 0);
555 return 0;
556}
557
558AddFileToDownloadsTable(String:filename[])
559{
560 static table = -1;
561 if (table == -1)
562 {
563 table = FindStringTable("downloadables");
564 }
565 new bool:save = LockStringTables(false);
566 AddToStringTable(table, filename, "", -1);
567 LockStringTables(save);
568 return 0;
569}
570
571Array_FindString(String:array[][], size, String:str[], bool:caseSensitive, start)
572{
573 if (0 > start)
574 {
575 start = 0;
576 }
577 new i = start;
578 while (i < size)
579 {
580 if (StrEqual(array[i], str, caseSensitive))
581 {
582 return i;
583 }
584 i++;
585 }
586 return -1;
587}
588
589Array_Copy(any:array[], any:newArray[], size)
590{
591 new i;
592 while (i < size)
593 {
594 newArray[i] = array[i];
595 i++;
596 }
597 return 0;
598}
599
600bool:isCSS()
601{
602 new String:sGameMode[64];
603 GetGameFolderName(sGameMode, 64);
604 return StrEqual(sGameMode, "cstrike", true);
605}
606
607CPrintToChat(client, String:message[])
608{
609 if (isCSS())
610 {
611 CCheckTrie();
612 new var1;
613 if (client <= 0 || client > MaxClients)
614 {
615 ThrowError(sm_show_activity, client);
616 }
617 if (!IsClientInGame(client))
618 {
619 ThrowError("Client %i is not in game", client);
620 }
621 decl String:buffer[512];
622 decl String:buffer2[512];
623 SetGlobalTransTarget(client);
624 Format(buffer, 512, "\x01%s", message);
625 VFormat(buffer2, 512, buffer, 3);
626 CReplaceColorCodes(buffer2, 512, 0, false);
627 CSendMessage(client, buffer2, 0);
628 }
629 else
630 {
631 new var2;
632 if (client <= 0 || client > MaxClients)
633 {
634 ThrowError("Invalid client index %d", client);
635 }
636 if (!IsClientInGame(client))
637 {
638 ThrowError("Client %d is not in game", client);
639 }
640 decl String:szBuffer[512];
641 decl String:szCMessage[512];
642 SetGlobalTransTarget(client);
643 Format(szBuffer, 512, "\x01%s", message);
644 VFormat(szCMessage, 512, szBuffer, 3);
645 new index = CReplaceColorCodes(szCMessage, 512, 0, false);
646 if (index == -1)
647 {
648 PrintToChat(client, "%s", szCMessage);
649 }
650 else
651 {
652 CSayText2(client, index, szCMessage);
653 }
654 }
655 return 0;
656}
657
658CPrintToChatAll(String:message[])
659{
660 if (isCSS())
661 {
662 CCheckTrie();
663 decl String:buffer[512];
664 decl String:buffer2[512];
665 new i = 1;
666 while (i <= MaxClients)
667 {
668 new var1;
669 if (!IsClientInGame(i) || CSkipList[i])
670 {
671 CSkipList[i] = 0;
672 }
673 else
674 {
675 SetGlobalTransTarget(i);
676 Format(buffer, 512, "\x01%s", message);
677 VFormat(buffer2, 512, buffer, 2);
678 CReplaceColorCodes(buffer2, 512, 0, false);
679 CSendMessage(i, buffer2, 0);
680 }
681 i++;
682 }
683 }
684 else
685 {
686 decl String:szBuffer[512];
687 new i = 1;
688 while (i <= MaxClients)
689 {
690 new var2;
691 if (IsClientInGame(i) && !IsFakeClient(i) && !CSkipList[i])
692 {
693 SetGlobalTransTarget(i);
694 VFormat(szBuffer, 512, message, 2);
695 CPrintToChat(i, "%s", szBuffer);
696 }
697 CSkipList[i] = 0;
698 i++;
699 }
700 }
701 return 0;
702}
703
704CSendMessage(client, String:message[], author)
705{
706 if (!author)
707 {
708 author = client;
709 }
710 decl String:buffer[512];
711 decl String:game[16];
712 GetGameFolderName(game, 16);
713 strcopy(buffer, 512, message);
714 new UserMsg:index = GetUserMessageId("SayText2");
715 if (index == UserMsg:-1)
716 {
717 if (StrEqual(game, "dod", true))
718 {
719 new team = GetClientTeam(author);
720 if (team)
721 {
722 decl String:temp[16];
723 new var2 = CTeamColors;
724 Format(temp, 16, "\x07%06X", var2[0][var2][team + -1]);
725 ReplaceString(buffer, 512, "\x03", temp, false);
726 }
727 else
728 {
729 ReplaceString(buffer, 512, "\x03", "\x04", false);
730 }
731 }
732 PrintToChat(client, "%s", buffer);
733 return 0;
734 }
735 new Handle:buf = StartMessageOne("SayText2", client, 132);
736 new var1;
737 if (GetFeatureStatus(FeatureType:0, "GetUserMessageType") && GetUserMessageType() == 1)
738 {
739 PbSetInt(buf, "ent_idx", author, -1);
740 PbSetBool(buf, "chat", true, -1);
741 PbSetString(buf, "msg_name", buffer, -1);
742 PbAddString(buf, "params", "");
743 PbAddString(buf, "params", "");
744 PbAddString(buf, "params", "");
745 PbAddString(buf, "params", "");
746 }
747 else
748 {
749 BfWriteByte(buf, author);
750 BfWriteByte(buf, 1);
751 BfWriteString(buf, buffer);
752 }
753 EndMessage();
754 return 0;
755}
756
757CCheckTrie()
758{
759 if (!CTrie)
760 {
761 CTrie = InitColorTrie();
762 }
763 return 0;
764}
765
766CReplaceColorCodes(String:buffer[], maxlen, author, bool:removeTags)
767{
768 if (isCSS())
769 {
770 CCheckTrie();
771 if (!removeTags)
772 {
773 ReplaceString(buffer, maxlen, "{default}", "\x01", false);
774 }
775 else
776 {
777 ReplaceString(buffer, maxlen, "{default}", "", false);
778 ReplaceString(buffer, maxlen, "{teamcolor}", "", false);
779 }
780 new var1;
781 if (author && !removeTags)
782 {
783 new var2;
784 if (author < 0 || author > MaxClients)
785 {
786 ThrowError("Invalid client index %i", author);
787 }
788 if (!IsClientInGame(author))
789 {
790 ThrowError("Client %i is not in game", author);
791 }
792 ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
793 }
794 new cursor;
795 new value;
796 decl String:tag[32];
797 decl String:buff[32];
798 decl output[maxlen];
799 strcopy(output, maxlen, buffer);
800 new Handle:regex = CompileRegex("{[a-zA-Z0-9]+}", 0, "", 0, 0);
801 new i;
802 while (i < 1000)
803 {
804 if (MatchRegex(regex, buffer[cursor], 0) < 1)
805 {
806 CloseHandle(regex);
807 strcopy(buffer, maxlen, output);
808 return 0;
809 }
810 GetRegexSubString(regex, 0, tag, 32);
811 CStrToLower(tag);
812 cursor = StrContains(buffer[cursor], tag, false) + cursor + 1;
813 strcopy(buff, 32, tag);
814 ReplaceString(buff, 32, "{", "", true);
815 ReplaceString(buff, 32, "}", "", true);
816 if (GetTrieValue(CTrie, buff, value))
817 {
818 if (removeTags)
819 {
820 ReplaceString(output, maxlen, tag, "", false);
821 }
822 else
823 {
824 Format(buff, 32, "\x07%06X", value);
825 ReplaceString(output, maxlen, tag, buff, false);
826 }
827 }
828 i++;
829 }
830 LogError("[MORE COLORS] Infinite loop broken.");
831 return 0;
832 }
833 decl String:szGameName[32];
834 GetGameFolderName(szGameName, 30);
835 if (!CEventIsHooked)
836 {
837 CSetupProfile();
838 HookEvent("server_spawn", CEvent_MapStart, EventHookMode:2);
839 CEventIsHooked = true;
840 }
841 new iRandomPlayer = -1;
842 if (StrEqual(szGameName, "csgo", false))
843 {
844 Format(buffer, maxlen, " \x01\x01%s", buffer);
845 }
846 if (author != -1)
847 {
848 if (CProfile_SayText2)
849 {
850 ReplaceString(buffer, maxlen, "{teamcolor}", "\x03", false);
851 iRandomPlayer = author;
852 }
853 else
854 {
855 ReplaceString(buffer, maxlen, "{teamcolor}", CTagCode[2], false);
856 }
857 }
858 else
859 {
860 ReplaceString(buffer, maxlen, "{teamcolor}", "", false);
861 }
862 new i;
863 while (i < 17)
864 {
865 if (!(StrContains(buffer, CTag[i], false) == -1))
866 {
867 if (!CProfile_Colors[i])
868 {
869 ReplaceString(buffer, maxlen, CTag[i], CTagCode[2], false);
870 }
871 else
872 {
873 if (!CTagReqSayText2[i])
874 {
875 ReplaceString(buffer, maxlen, CTag[i], CTagCode[i], false);
876 }
877 if (!CProfile_SayText2)
878 {
879 ReplaceString(buffer, maxlen, CTag[i], CTagCode[2], false);
880 }
881 if (iRandomPlayer == -1)
882 {
883 iRandomPlayer = CFindRandomPlayerByTeam(CProfile_TeamIndex[i]);
884 if (iRandomPlayer == -2)
885 {
886 ReplaceString(buffer, maxlen, CTag[i], CTagCode[2], false);
887 }
888 else
889 {
890 ReplaceString(buffer, maxlen, CTag[i], CTagCode[i], false);
891 }
892 }
893 }
894 }
895 i++;
896 }
897 return iRandomPlayer;
898}
899
900CStrToLower(String:buffer[])
901{
902 new len = strlen(buffer);
903 new i;
904 while (i < len)
905 {
906 buffer[i] = CharToLower(buffer[i]);
907 i++;
908 }
909 return 0;
910}
911
912CFindRandomPlayerByTeam(color_team)
913{
914 if (color_team)
915 {
916 new i = 1;
917 while (i <= MaxClients)
918 {
919 new var1;
920 if (IsClientInGame(i) && color_team == GetClientTeam(i))
921 {
922 return i;
923 }
924 i++;
925 }
926 return -2;
927 }
928 return 0;
929}
930
931CSayText2(client, author, String:message[])
932{
933 new Handle:hBuffer = StartMessageOne("SayText2", client, 132);
934 new var1;
935 if (GetFeatureStatus(FeatureType:0, "GetUserMessageType") && GetUserMessageType() == 1)
936 {
937 PbSetInt(hBuffer, "ent_idx", author, -1);
938 PbSetBool(hBuffer, "chat", true, -1);
939 PbSetString(hBuffer, "msg_name", message, -1);
940 PbAddString(hBuffer, "params", "");
941 PbAddString(hBuffer, "params", "");
942 PbAddString(hBuffer, "params", "");
943 PbAddString(hBuffer, "params", "");
944 }
945 else
946 {
947 BfWriteByte(hBuffer, author);
948 BfWriteByte(hBuffer, 1);
949 BfWriteString(hBuffer, message);
950 }
951 EndMessage();
952 return 0;
953}
954
955CSetupProfile()
956{
957 decl String:szGameName[32];
958 GetGameFolderName(szGameName, 30);
959 if (StrEqual(szGameName, "cstrike", false))
960 {
961 CProfile_Colors[3] = 1;
962 CProfile_Colors[8] = 1;
963 CProfile_Colors[5] = 1;
964 CProfile_Colors[6] = 1;
965 CProfile_TeamIndex[3] = 0;
966 CProfile_TeamIndex[8] = 2;
967 CProfile_TeamIndex[5] = 3;
968 CProfile_SayText2 = true;
969 }
970 else
971 {
972 if (StrEqual(szGameName, "csgo", false))
973 {
974 CProfile_Colors[4] = 1;
975 CProfile_Colors[5] = 1;
976 CProfile_Colors[6] = 1;
977 CProfile_Colors[1] = 1;
978 CProfile_Colors[7] = 1;
979 CProfile_Colors[9] = 1;
980 CProfile_Colors[10] = 1;
981 CProfile_Colors[11] = 1;
982 CProfile_Colors[12] = 1;
983 CProfile_Colors[13] = 1;
984 CProfile_Colors[14] = 1;
985 CProfile_Colors[15] = 1;
986 CProfile_Colors[16] = 1;
987 CProfile_TeamIndex[8] = 2;
988 CProfile_TeamIndex[5] = 3;
989 CProfile_SayText2 = true;
990 }
991 if (StrEqual(szGameName, "tf", false))
992 {
993 CProfile_Colors[3] = 1;
994 CProfile_Colors[8] = 1;
995 CProfile_Colors[5] = 1;
996 CProfile_Colors[6] = 1;
997 CProfile_TeamIndex[3] = 0;
998 CProfile_TeamIndex[8] = 2;
999 CProfile_TeamIndex[5] = 3;
1000 CProfile_SayText2 = true;
1001 }
1002 new var1;
1003 if (StrEqual(szGameName, "left4dead", false) || StrEqual(szGameName, "left4dead2", false))
1004 {
1005 CProfile_Colors[3] = 1;
1006 CProfile_Colors[8] = 1;
1007 CProfile_Colors[5] = 1;
1008 CProfile_Colors[6] = 1;
1009 CProfile_TeamIndex[3] = 0;
1010 CProfile_TeamIndex[8] = 3;
1011 CProfile_TeamIndex[5] = 2;
1012 CProfile_SayText2 = true;
1013 }
1014 if (StrEqual(szGameName, "hl2mp", false))
1015 {
1016 if (GetConVarBool(FindConVar("mp_teamplay")))
1017 {
1018 CProfile_Colors[8] = 1;
1019 CProfile_Colors[5] = 1;
1020 CProfile_Colors[6] = 1;
1021 CProfile_TeamIndex[8] = 3;
1022 CProfile_TeamIndex[5] = 2;
1023 CProfile_SayText2 = true;
1024 }
1025 else
1026 {
1027 CProfile_SayText2 = false;
1028 CProfile_Colors[6] = 1;
1029 }
1030 }
1031 if (StrEqual(szGameName, "dod", false))
1032 {
1033 CProfile_Colors[6] = 1;
1034 CProfile_SayText2 = false;
1035 }
1036 if (GetUserMessageId("SayText2") == -1)
1037 {
1038 CProfile_SayText2 = false;
1039 }
1040 CProfile_Colors[8] = 1;
1041 CProfile_Colors[5] = 1;
1042 CProfile_TeamIndex[8] = 2;
1043 CProfile_TeamIndex[5] = 3;
1044 CProfile_SayText2 = true;
1045 }
1046 return 0;
1047}
1048
1049public Action:CEvent_MapStart(Handle:event, String:name[], bool:dontBroadcast)
1050{
1051 CSetupProfile();
1052 new i = 1;
1053 while (i <= MaxClients)
1054 {
1055 CSkipList[i] = 0;
1056 i++;
1057 }
1058 return Action:0;
1059}
1060
1061Handle:InitColorTrie()
1062{
1063 new Handle:hTrie = CreateTrie();
1064 SetTrieValue(hTrie, "aliceblue", any:15792383, true);
1065 SetTrieValue(hTrie, "timerblue", any:65471, true);
1066 SetTrieValue(hTrie, "allies", any:5077314, true);
1067 SetTrieValue(hTrie, "antiquewhite", any:16444375, true);
1068 SetTrieValue(hTrie, "aqua", any:65535, true);
1069 SetTrieValue(hTrie, "aquamarine", any:8388564, true);
1070 SetTrieValue(hTrie, "axis", any:16728128, true);
1071 SetTrieValue(hTrie, "azure", any:32767, true);
1072 SetTrieValue(hTrie, "beige", any:16119260, true);
1073 SetTrieValue(hTrie, "bisque", any:16770244, true);
1074 SetTrieValue(hTrie, "black", any:0, true);
1075 SetTrieValue(hTrie, "blanchedalmond", any:16772045, true);
1076 SetTrieValue(hTrie, "blue", any:10079487, true);
1077 SetTrieValue(hTrie, "blueviolet", any:9055202, true);
1078 SetTrieValue(hTrie, "brown", any:10824234, true);
1079 SetTrieValue(hTrie, "burlywood", any:14596231, true);
1080 SetTrieValue(hTrie, "cadetblue", any:6266528, true);
1081 SetTrieValue(hTrie, "chartreuse", any:8388352, true);
1082 SetTrieValue(hTrie, "chocolate", any:13789470, true);
1083 SetTrieValue(hTrie, "community", any:7385162, true);
1084 SetTrieValue(hTrie, "coral", any:16744272, true);
1085 SetTrieValue(hTrie, "cornflowerblue", any:6591981, true);
1086 SetTrieValue(hTrie, "cornsilk", any:16775388, true);
1087 SetTrieValue(hTrie, "crimson", any:14423100, true);
1088 SetTrieValue(hTrie, "cyan", any:65535, true);
1089 SetTrieValue(hTrie, "darkblue", any:139, true);
1090 SetTrieValue(hTrie, "darkcyan", any:35723, true);
1091 SetTrieValue(hTrie, "darkgoldenrod", any:12092939, true);
1092 SetTrieValue(hTrie, "darkgray", any:11119017, true);
1093 SetTrieValue(hTrie, "darkgrey", any:11119017, true);
1094 SetTrieValue(hTrie, "darkgreen", any:25600, true);
1095 SetTrieValue(hTrie, "darkkhaki", any:12433259, true);
1096 SetTrieValue(hTrie, "darkmagenta", any:9109643, true);
1097 SetTrieValue(hTrie, "darkolivegreen", any:5597999, true);
1098 SetTrieValue(hTrie, "darkorange", any:16747520, true);
1099 SetTrieValue(hTrie, "darkorchid", any:10040012, true);
1100 SetTrieValue(hTrie, "darkred", any:9109504, true);
1101 SetTrieValue(hTrie, "darksalmon", any:15308410, true);
1102 SetTrieValue(hTrie, "darkseagreen", any:9419919, true);
1103 SetTrieValue(hTrie, "darkslateblue", any:4734347, true);
1104 SetTrieValue(hTrie, "darkslategray", any:3100495, true);
1105 SetTrieValue(hTrie, "darkslategrey", any:3100495, true);
1106 SetTrieValue(hTrie, "darkturquoise", any:52945, true);
1107 SetTrieValue(hTrie, "darkviolet", any:9699539, true);
1108 SetTrieValue(hTrie, "deeppink", any:16716947, true);
1109 SetTrieValue(hTrie, "deepskyblue", any:49151, true);
1110 SetTrieValue(hTrie, "dimgray", any:6908265, true);
1111 SetTrieValue(hTrie, "dimgrey", any:6908265, true);
1112 SetTrieValue(hTrie, "dodgerblue", any:2003199, true);
1113 SetTrieValue(hTrie, "firebrick", any:11674146, true);
1114 SetTrieValue(hTrie, "floralwhite", any:16775920, true);
1115 SetTrieValue(hTrie, "forestgreen", any:2263842, true);
1116 SetTrieValue(hTrie, "fuchsia", any:16711935, true);
1117 SetTrieValue(hTrie, "fullblue", any:255, true);
1118 SetTrieValue(hTrie, "fullred", any:16711680, true);
1119 SetTrieValue(hTrie, "gainsboro", any:14474460, true);
1120 SetTrieValue(hTrie, "genuine", any:5076053, true);
1121 SetTrieValue(hTrie, "ghostwhite", any:16316671, true);
1122 SetTrieValue(hTrie, "gold", any:16766720, true);
1123 SetTrieValue(hTrie, "goldenrod", any:14329120, true);
1124 SetTrieValue(hTrie, "gray", any:13421772, true);
1125 SetTrieValue(hTrie, "grey", any:13421772, true);
1126 SetTrieValue(hTrie, "green", any:4128574, true);
1127 SetTrieValue(hTrie, "greenyellow", any:11403055, true);
1128 SetTrieValue(hTrie, "haunted", any:3732395, true);
1129 SetTrieValue(hTrie, "honeydew", any:15794160, true);
1130 SetTrieValue(hTrie, "hotpink", any:16738740, true);
1131 SetTrieValue(hTrie, "indianred", any:13458524, true);
1132 SetTrieValue(hTrie, "indigo", any:4915330, true);
1133 SetTrieValue(hTrie, "ivory", any:16777200, true);
1134 SetTrieValue(hTrie, "khaki", any:15787660, true);
1135 SetTrieValue(hTrie, "lavender", any:15132410, true);
1136 SetTrieValue(hTrie, "lavenderblush", any:16773365, true);
1137 SetTrieValue(hTrie, "lawngreen", any:8190976, true);
1138 SetTrieValue(hTrie, "lemonchiffon", any:16775885, true);
1139 SetTrieValue(hTrie, "lightblue", any:11393254, true);
1140 SetTrieValue(hTrie, "lightcoral", any:15761536, true);
1141 SetTrieValue(hTrie, "lightcyan", any:14745599, true);
1142 SetTrieValue(hTrie, "lightgoldenrodyellow", any:16448210, true);
1143 SetTrieValue(hTrie, "lightgray", any:13882323, true);
1144 SetTrieValue(hTrie, "lightgrey", any:13882323, true);
1145 SetTrieValue(hTrie, "lightgreen", any:10092441, true);
1146 SetTrieValue(hTrie, "lightpink", any:16758465, true);
1147 SetTrieValue(hTrie, "lightsalmon", any:16752762, true);
1148 SetTrieValue(hTrie, "lightseagreen", any:2142890, true);
1149 SetTrieValue(hTrie, "lightskyblue", any:8900346, true);
1150 SetTrieValue(hTrie, "lightslategray", any:7833753, true);
1151 SetTrieValue(hTrie, "lightslategrey", any:7833753, true);
1152 SetTrieValue(hTrie, "lightsteelblue", any:11584734, true);
1153 SetTrieValue(hTrie, "lightyellow", any:16777184, true);
1154 SetTrieValue(hTrie, "lime", any:65280, true);
1155 SetTrieValue(hTrie, "limegreen", any:3329330, true);
1156 SetTrieValue(hTrie, "linen", any:16445670, true);
1157 SetTrieValue(hTrie, "magenta", any:16711935, true);
1158 SetTrieValue(hTrie, "maroon", any:8388608, true);
1159 SetTrieValue(hTrie, "mediumaquamarine", any:6737322, true);
1160 SetTrieValue(hTrie, "mediumblue", any:205, true);
1161 SetTrieValue(hTrie, "mediumorchid", any:12211667, true);
1162 SetTrieValue(hTrie, "mediumpurple", any:9662680, true);
1163 SetTrieValue(hTrie, "mediumseagreen", any:3978097, true);
1164 SetTrieValue(hTrie, "mediumslateblue", any:8087790, true);
1165 SetTrieValue(hTrie, "mediumspringgreen", any:64154, true);
1166 SetTrieValue(hTrie, "mediumturquoise", any:4772300, true);
1167 SetTrieValue(hTrie, "mediumvioletred", any:13047173, true);
1168 SetTrieValue(hTrie, "midnightblue", any:1644912, true);
1169 SetTrieValue(hTrie, "mintcream", any:16121850, true);
1170 SetTrieValue(hTrie, "mistyrose", any:16770273, true);
1171 SetTrieValue(hTrie, "moccasin", any:16770229, true);
1172 SetTrieValue(hTrie, "navajowhite", any:16768685, true);
1173 SetTrieValue(hTrie, "navy", any:128, true);
1174 SetTrieValue(hTrie, "normal", any:11711154, true);
1175 SetTrieValue(hTrie, "oldlace", any:16643558, true);
1176 SetTrieValue(hTrie, "olive", any:10404687, true);
1177 SetTrieValue(hTrie, "olivedrab", any:7048739, true);
1178 SetTrieValue(hTrie, "orange", any:16753920, true);
1179 SetTrieValue(hTrie, "orangered", any:16729344, true);
1180 SetTrieValue(hTrie, "orchid", any:14315734, true);
1181 SetTrieValue(hTrie, "palegoldenrod", any:15657130, true);
1182 SetTrieValue(hTrie, "palegreen", any:10025880, true);
1183 SetTrieValue(hTrie, "paleturquoise", any:11529966, true);
1184 SetTrieValue(hTrie, "palevioletred", any:14184595, true);
1185 SetTrieValue(hTrie, "papayawhip", any:16773077, true);
1186 SetTrieValue(hTrie, "peachpuff", any:16767673, true);
1187 SetTrieValue(hTrie, "peru", any:13468991, true);
1188 SetTrieValue(hTrie, "pink", any:16761035, true);
1189 SetTrieValue(hTrie, "plum", any:14524637, true);
1190 SetTrieValue(hTrie, "powderblue", any:11591910, true);
1191 SetTrieValue(hTrie, "purple", any:8388736, true);
1192 SetTrieValue(hTrie, "red", any:16728128, true);
1193 SetTrieValue(hTrie, "rosybrown", any:12357519, true);
1194 SetTrieValue(hTrie, "royalblue", any:4286945, true);
1195 SetTrieValue(hTrie, "saddlebrown", any:9127187, true);
1196 SetTrieValue(hTrie, "salmon", any:16416882, true);
1197 SetTrieValue(hTrie, "sandybrown", any:16032864, true);
1198 SetTrieValue(hTrie, "seagreen", any:3050327, true);
1199 SetTrieValue(hTrie, "seashell", any:16774638, true);
1200 SetTrieValue(hTrie, "selfmade", any:7385162, true);
1201 SetTrieValue(hTrie, "sienna", any:10506797, true);
1202 SetTrieValue(hTrie, "silver", any:12632256, true);
1203 SetTrieValue(hTrie, "skyblue", any:8900331, true);
1204 SetTrieValue(hTrie, "slateblue", any:6970061, true);
1205 SetTrieValue(hTrie, "slategray", any:7372944, true);
1206 SetTrieValue(hTrie, "slategrey", any:7372944, true);
1207 SetTrieValue(hTrie, "snow", any:16775930, true);
1208 SetTrieValue(hTrie, "springgreen", any:65407, true);
1209 SetTrieValue(hTrie, "steelblue", any:4620980, true);
1210 SetTrieValue(hTrie, "strange", any:13593138, true);
1211 SetTrieValue(hTrie, "tan", any:13808780, true);
1212 SetTrieValue(hTrie, "teal", any:32896, true);
1213 SetTrieValue(hTrie, "thistle", any:14204888, true);
1214 SetTrieValue(hTrie, "tomato", any:16737095, true);
1215 SetTrieValue(hTrie, "turquoise", any:4251856, true);
1216 SetTrieValue(hTrie, "unique", any:16766720, true);
1217 SetTrieValue(hTrie, "unusual", any:8802476, true);
1218 SetTrieValue(hTrie, "valve", any:10817401, true);
1219 SetTrieValue(hTrie, "vintage", any:4678289, true);
1220 SetTrieValue(hTrie, "violet", any:15631086, true);
1221 SetTrieValue(hTrie, "wheat", any:16113331, true);
1222 SetTrieValue(hTrie, "white", any:16777215, true);
1223 SetTrieValue(hTrie, "whitesmoke", any:16119285, true);
1224 SetTrieValue(hTrie, "yellow", any:16776960, true);
1225 SetTrieValue(hTrie, "yellowgreen", any:10145074, true);
1226 SetTrieValue(hTrie, "boss1", any:3706510, true);
1227 SetTrieValue(hTrie, "boss2", any:7396315, true);
1228 SetTrieValue(hTrie, "boss3", any:3158064, true);
1229 return hTrie;
1230}
1231
1232Entity_IsValid(entity)
1233{
1234 return IsValidEntity(entity);
1235}
1236
1237bool:Entity_IsPlayer(entity)
1238{
1239 new var1;
1240 if (entity < 1 || entity > MaxClients)
1241 {
1242 return false;
1243 }
1244 return true;
1245}
1246
1247bool:Entity_Kill(kenny, killChildren)
1248{
1249 if (Entity_IsPlayer(kenny))
1250 {
1251 ForcePlayerSuicide(kenny);
1252 return true;
1253 }
1254 if (killChildren)
1255 {
1256 return AcceptEntityInput(kenny, localIPRanges, -1, -1, 0);
1257 }
1258 return AcceptEntityInput(kenny, "Kill", -1, -1, 0);
1259}
1260
1261public Action:__smlib_Timer_ChangeOverTime(Handle:Timer, Handle:dataPack)
1262{
1263 new entity = EntRefToEntIndex(ReadPackCell(dataPack));
1264 if (!Entity_IsValid(entity))
1265 {
1266 return Action:4;
1267 }
1268 new Float:interval = ReadPackFloat(dataPack);
1269 new currentCall = ReadPackCell(dataPack);
1270 new Function:callback = ReadPackFunction(dataPack);
1271 new any:result;
1272 Call_StartFunction(Handle:0, callback);
1273 Call_PushCellRef(entity);
1274 Call_PushFloatRef(interval);
1275 Call_PushCellRef(currentCall);
1276 Call_Finish(result);
1277 if (result)
1278 {
1279 ResetPack(dataPack, true);
1280 WritePackCell(dataPack, EntIndexToEntRef(entity));
1281 WritePackFloat(dataPack, interval);
1282 WritePackCell(dataPack, currentCall + 1);
1283 WritePackFunction(dataPack, callback);
1284 ResetPack(dataPack, false);
1285 CreateTimer(interval, __smlib_Timer_ChangeOverTime, dataPack, 0);
1286 return Action:4;
1287 }
1288 return Action:4;
1289}
1290
1291Team_GetAnyClient(index)
1292{
1293 static client_cache[32] =
1294 {
1295 -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1296 };
1297 new client;
1298 if (0 < index)
1299 {
1300 client = client_cache[index];
1301 new var1;
1302 if (client > 0 && client <= MaxClients)
1303 {
1304 new var2;
1305 if (IsClientInGame(client) && index == GetClientTeam(client))
1306 {
1307 return client;
1308 }
1309 }
1310 client = -1;
1311 }
1312 client = 1;
1313 while (client <= MaxClients)
1314 {
1315 if (IsClientInGame(client))
1316 {
1317 if (!(index != GetClientTeam(client)))
1318 {
1319 client_cache[index] = client;
1320 return client;
1321 }
1322 }
1323 client++;
1324 }
1325 return -1;
1326}
1327
1328Color_ChatInitialize()
1329{
1330 static initialized;
1331 if (initialized)
1332 {
1333 return 0;
1334 }
1335 initialized = 1;
1336 decl String:gameFolderName[32];
1337 GetGameFolderName(gameFolderName, 32);
1338 chatColorInfo[11][2] = 0;
1339 new var1;
1340 if (strncmp(gameFolderName, "left4dead", 9, false) && !StrEqual(gameFolderName, "cstrike", false) && !StrEqual(gameFolderName, "tf", false))
1341 {
1342 chatColorInfo[7][2] = 0;
1343 chatColorInfo[8][2] = 0;
1344 }
1345 if (StrEqual(gameFolderName, "tf", false))
1346 {
1347 chatColorInfo[11][2] = 1;
1348 chatColorInfo[8] = 1;
1349 chatColorInfo[8][3] = -3;
1350 }
1351 else
1352 {
1353 if (strncmp(gameFolderName, "left4dead", 9, false))
1354 {
1355 if (StrEqual(gameFolderName, "hl2mp", false))
1356 {
1357 chatColorInfo[2][3] = 3;
1358 chatColorInfo[3][3] = 3;
1359 chatColorInfo[4][3] = 2;
1360 chatColorInfo[5][3] = 2;
1361 chatColorInfo[11][2] = 1;
1362 checkTeamPlay = true;
1363 }
1364 if (StrEqual(gameFolderName, "dod", false))
1365 {
1366 chatColorInfo[8] = 1;
1367 chatColorInfo[8][3] = -3;
1368 chatColorInfo[11][2] = 1;
1369 chatColorInfo[1][2] = 0;
1370 }
1371 }
1372 chatColorInfo[2][3] = 3;
1373 chatColorInfo[3][3] = 3;
1374 chatColorInfo[4][3] = 2;
1375 chatColorInfo[5][3] = 2;
1376 chatColorInfo[1] = 4;
1377 chatColorInfo[9] = 5;
1378 }
1379 if (GetUserMessageId("SayText2") == -1)
1380 {
1381 isSayText2_supported = false;
1382 }
1383 decl String:path_gamedata[256];
1384 BuildPath(PathType:0, path_gamedata, 256, "gamedata/%s.txt", "smlib_colors.games");
1385 if (FileExists(path_gamedata, false, "GAME"))
1386 {
1387 new Handle:gamedata;
1388 if ((gamedata = LoadGameConfigFile("smlib_colors.games")))
1389 {
1390 decl String:keyName[32];
1391 decl String:buffer[8];
1392 new i;
1393 while (i < 12)
1394 {
1395 Format(keyName, 32, "%s_code", chatColorNames[i]);
1396 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
1397 {
1398 chatColorInfo[i][0] = StringToInt(buffer, 10);
1399 }
1400 Format(keyName, 32, "%s_alternative", chatColorNames[i]);
1401 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
1402 {
1403 chatColorInfo[i][1] = buffer[0];
1404 }
1405 Format(keyName, 32, "%s_supported", chatColorNames[i]);
1406 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
1407 {
1408 chatColorInfo[i][2] = StrEqual(buffer, "true", true);
1409 }
1410 Format(keyName, 32, "%s_subjecttype", chatColorNames[i]);
1411 if (GameConfGetKeyValue(gamedata, keyName, buffer, 6))
1412 {
1413 chatColorInfo[i][3] = StringToInt(buffer, 10);
1414 }
1415 i++;
1416 }
1417 if (GameConfGetKeyValue(gamedata, "checkteamplay", buffer, 6))
1418 {
1419 checkTeamPlay = StrEqual(buffer, "true", true);
1420 }
1421 CloseHandle(gamedata);
1422 }
1423 }
1424 mp_teamplay = FindConVar("mp_teamplay");
1425 return 0;
1426}
1427
1428Color_GetChatColorInfo(&index, &subject)
1429{
1430 Color_ChatInitialize();
1431 if (index == -1)
1432 {
1433 index = 0;
1434 }
1435 while (!chatColorInfo[index][2])
1436 {
1437 new alternative = chatColorInfo[index][1];
1438 if (alternative == -1)
1439 {
1440 index = 0;
1441 if (index == -1)
1442 {
1443 index = 0;
1444 }
1445 new newSubject = -2;
1446 new ChatColorSubjectType:type = chatColorInfo[index][3];
1447 switch (type)
1448 {
1449 case -3:
1450 {
1451 }
1452 case -2:
1453 {
1454 newSubject = chatSubject;
1455 }
1456 case -1:
1457 {
1458 newSubject = -1;
1459 }
1460 case 0:
1461 {
1462 newSubject = 0;
1463 }
1464 default:
1465 {
1466 new var1;
1467 if (!checkTeamPlay || GetConVarBool(mp_teamplay))
1468 {
1469 new var2;
1470 if (subject > 0 && subject <= MaxClients)
1471 {
1472 if (type == GetClientTeam(subject))
1473 {
1474 newSubject = subject;
1475 }
1476 }
1477 if (subject == -2)
1478 {
1479 new client = Team_GetAnyClient(type);
1480 if (client != -1)
1481 {
1482 newSubject = client;
1483 }
1484 }
1485 }
1486 }
1487 }
1488 new var5;
1489 if (type > ChatColorSubjectType:-3 && ((subject != -2 && newSubject != subject) || (newSubject == -2 || !isSayText2_supported)))
1490 {
1491 index = chatColorInfo[index][1];
1492 newSubject = Color_GetChatColorInfo(index, subject);
1493 }
1494 if (subject == -2)
1495 {
1496 subject = newSubject;
1497 }
1498 return newSubject;
1499 }
1500 index = alternative;
1501 }
1502 if (index == -1)
1503 {
1504 index = 0;
1505 }
1506 new newSubject = -2;
1507 new ChatColorSubjectType:type = chatColorInfo[index][3];
1508 switch (type)
1509 {
1510 case -3:
1511 {
1512 }
1513 case -2:
1514 {
1515 newSubject = chatSubject;
1516 }
1517 case -1:
1518 {
1519 newSubject = -1;
1520 }
1521 case 0:
1522 {
1523 newSubject = 0;
1524 }
1525 default:
1526 {
1527 new var1;
1528 if (!checkTeamPlay || GetConVarBool(mp_teamplay))
1529 {
1530 new var2;
1531 if (subject > 0 && subject <= MaxClients)
1532 {
1533 if (type == GetClientTeam(subject))
1534 {
1535 newSubject = subject;
1536 }
1537 }
1538 if (subject == -2)
1539 {
1540 new client = Team_GetAnyClient(type);
1541 if (client != -1)
1542 {
1543 newSubject = client;
1544 }
1545 }
1546 }
1547 }
1548 }
1549 new var5;
1550 if (type > ChatColorSubjectType:-3 && ((subject != -2 && newSubject != subject) || (newSubject == -2 || !isSayText2_supported)))
1551 {
1552 index = chatColorInfo[index][1];
1553 newSubject = Color_GetChatColorInfo(index, subject);
1554 }
1555 if (subject == -2)
1556 {
1557 subject = newSubject;
1558 }
1559 return newSubject;
1560}
1561
1562public bool:_smlib_TraceEntityFilter(entity, contentsMask)
1563{
1564 return entity == 0;
1565}
1566
1567public __smlib_GetPlayersInRadius_Sort(player1, player2, clients[], Handle:hndl)
1568{
1569 return FloatCompare(getPlayersInRadius_distances[player1], getPlayersInRadius_distances[player2]);
1570}
1571
1572public Action:_smlib_Timer_Effect_Fade(Handle:Timer, Handle:dataPack)
1573{
1574 new entity = ReadPackCell(dataPack);
1575 new kill = ReadPackCell(dataPack);
1576 new Function:callback = ReadPackFunction(dataPack);
1577 new any:data = ReadPackCell(dataPack);
1578 if (callback != -1)
1579 {
1580 Call_StartFunction(Handle:0, callback);
1581 Call_PushCell(entity);
1582 Call_PushCell(data);
1583 Call_Finish(0);
1584 }
1585 new var1;
1586 if (kill && IsValidEntity(entity))
1587 {
1588 Entity_Kill(entity, 0);
1589 }
1590 return Action:4;
1591}
1592
1593bool:File_GetBaseName(String:path[], String:buffer[], size)
1594{
1595 if (path[0])
1596 {
1597 new pos_start = FindCharInString(path, String:47, true);
1598 if (pos_start == -1)
1599 {
1600 pos_start = FindCharInString(path, String:92, true);
1601 }
1602 pos_start++;
1603 strcopy(buffer, size, path[pos_start]);
1604 return false;
1605 }
1606 buffer[0] = MissingTAG:0;
1607 return false;
1608}
1609
1610bool:File_GetDirName(String:path[], String:buffer[], size)
1611{
1612 if (path[0])
1613 {
1614 new pos_start = FindCharInString(path, String:47, true);
1615 if (pos_start == -1)
1616 {
1617 pos_start = FindCharInString(path, String:92, true);
1618 if (pos_start == -1)
1619 {
1620 buffer[0] = MissingTAG:0;
1621 return false;
1622 }
1623 }
1624 strcopy(buffer, size, path);
1625 buffer[pos_start] = MissingTAG:0;
1626 return false;
1627 }
1628 buffer[0] = MissingTAG:0;
1629 return false;
1630}
1631
1632bool:File_GetFileName(String:path[], String:buffer[], size)
1633{
1634 if (path[0])
1635 {
1636 File_GetBaseName(path, buffer, size);
1637 new pos_ext = FindCharInString(buffer, String:46, true);
1638 if (pos_ext != -1)
1639 {
1640 buffer[pos_ext] = MissingTAG:0;
1641 }
1642 return false;
1643 }
1644 buffer[0] = MissingTAG:0;
1645 return false;
1646}
1647
1648File_GetExtension(String:path[], String:buffer[], size)
1649{
1650 new extpos = FindCharInString(path, String:46, true);
1651 if (extpos == -1)
1652 {
1653 buffer[0] = MissingTAG:0;
1654 return 0;
1655 }
1656 extpos++;
1657 strcopy(buffer, size, path[extpos]);
1658 return 0;
1659}
1660
1661File_AddToDownloadsTable(String:path[], bool:recursive, String:ignoreExts[][], size)
1662{
1663 if (path[0])
1664 {
1665 if (FileExists(path, false, "GAME"))
1666 {
1667 new String:fileExtension[8];
1668 File_GetExtension(path, fileExtension, 5);
1669 new var1;
1670 if (StrEqual(fileExtension, _smlib_empty_twodimstring_array, false) || StrEqual(fileExtension, "ztmp", false))
1671 {
1672 return 0;
1673 }
1674 if (Array_FindString(ignoreExts, size, fileExtension, true, 0) != -1)
1675 {
1676 return 0;
1677 }
1678 decl String:path_new[256];
1679 strcopy(path_new, 256, path);
1680 ReplaceString(path_new, 256, "//", "/", true);
1681 AddFileToDownloadsTable(path_new);
1682 }
1683 else
1684 {
1685 new var2;
1686 if (recursive && DirExists(path, false, "GAME"))
1687 {
1688 decl String:dirEntry[256];
1689 new Handle:__dir = OpenDirectory(path, false, "GAME");
1690 while (ReadDirEntry(__dir, dirEntry, 256, 0))
1691 {
1692 new var3;
1693 if (!(StrEqual(dirEntry, ".", true) || StrEqual(dirEntry, "..", true)))
1694 {
1695 Format(dirEntry, 256, "%s/%s", path, dirEntry);
1696 File_AddToDownloadsTable(dirEntry, recursive, ignoreExts, size);
1697 }
1698 }
1699 CloseHandle(__dir);
1700 }
1701 if (FindCharInString(path, String:42, true))
1702 {
1703 new String:fileExtension[4];
1704 File_GetExtension(path, fileExtension, 4);
1705 if (StrEqual(fileExtension, "*", true))
1706 {
1707 decl String:dirName[256];
1708 decl String:fileName[256];
1709 decl String:dirEntry[256];
1710 File_GetDirName(path, dirName, 256);
1711 File_GetFileName(path, fileName, 256);
1712 StrCat(fileName, 256, ".");
1713 new Handle:__dir = OpenDirectory(dirName, false, "GAME");
1714 while (ReadDirEntry(__dir, dirEntry, 256, 0))
1715 {
1716 new var4;
1717 if (!(StrEqual(dirEntry, ".", true) || StrEqual(dirEntry, "..", true)))
1718 {
1719 if (strncmp(dirEntry, fileName, strlen(fileName), true))
1720 {
1721 }
1722 else
1723 {
1724 Format(dirEntry, 256, "%s/%s", dirName, dirEntry);
1725 File_AddToDownloadsTable(dirEntry, recursive, ignoreExts, size);
1726 }
1727 }
1728 }
1729 CloseHandle(__dir);
1730 }
1731 }
1732 }
1733 return 0;
1734 }
1735 return 0;
1736}
1737
1738bool:File_Copy(String:source[], String:destination[])
1739{
1740 new Handle:file_source = OpenFile(source, "rb", false, "GAME");
1741 if (file_source)
1742 {
1743 new Handle:file_destination = OpenFile(destination, "wb", false, "GAME");
1744 if (file_destination)
1745 {
1746 new buffer[32];
1747 new cache;
1748 while (!IsEndOfFile(file_source))
1749 {
1750 cache = ReadFile(file_source, buffer, 32, 1);
1751 WriteFile(file_destination, buffer, cache, 1);
1752 }
1753 CloseHandle(file_source);
1754 CloseHandle(file_destination);
1755 return true;
1756 }
1757 CloseHandle(file_source);
1758 return false;
1759 }
1760 return false;
1761}
1762
1763bool:File_CopyRecursive(String:path[], String:destination[], bool:stop_on_error, dirMode)
1764{
1765 if (FileExists(path, false, "GAME"))
1766 {
1767 return File_Copy(path, destination);
1768 }
1769 if (DirExists(path, false, "GAME"))
1770 {
1771 return Sub_File_CopyRecursive(path, destination, stop_on_error, FileType:1, dirMode);
1772 }
1773 return false;
1774}
1775
1776bool:Sub_File_CopyRecursive(String:path[], String:destination[], bool:stop_on_error, FileType:fileType, dirMode)
1777{
1778 if (fileType == FileType:2)
1779 {
1780 return File_Copy(path, destination);
1781 }
1782 if (fileType == FileType:1)
1783 {
1784 new var1;
1785 if (!CreateDirectory(destination, dirMode, false, "DEFAULT_WRITE_PATH") && stop_on_error)
1786 {
1787 return false;
1788 }
1789 new Handle:directory = OpenDirectory(path, false, "GAME");
1790 if (directory)
1791 {
1792 decl String:source_buffer[256];
1793 decl String:destination_buffer[256];
1794 new FileType:type;
1795 while (ReadDirEntry(directory, source_buffer, 256, type))
1796 {
1797 new var2;
1798 if (!(StrEqual(source_buffer, "..", true) || StrEqual(source_buffer, ".", true)))
1799 {
1800 Format(destination_buffer, 256, "%s/%s", destination, source_buffer);
1801 Format(source_buffer, 256, "%s/%s", path, source_buffer);
1802 if (type == FileType:2)
1803 {
1804 File_Copy(source_buffer, destination_buffer);
1805 }
1806 else
1807 {
1808 if (type == FileType:1)
1809 {
1810 new var3;
1811 if (!File_CopyRecursive(source_buffer, destination_buffer, stop_on_error, dirMode) && stop_on_error)
1812 {
1813 CloseHandle(directory);
1814 return false;
1815 }
1816 }
1817 }
1818 }
1819 }
1820 CloseHandle(directory);
1821 }
1822 return false;
1823 }
1824 else
1825 {
1826 if (!fileType)
1827 {
1828 return false;
1829 }
1830 }
1831 return true;
1832}
1833
1834Timer_SecondsToTimeWr(Float:seconds, String:buffer[], maxlength, bool:precision)
1835{
1836 new t = RoundToFloor(seconds);
1837 new hour;
1838 new mins;
1839 if (t >= 3600)
1840 {
1841 hour = RoundToFloor(t / 1163984896);
1842 t %= 3600;
1843 }
1844 if (t >= 60)
1845 {
1846 mins = RoundToFloor(t / 1114636288);
1847 t %= 60;
1848 }
1849 Format(buffer, maxlength, "");
1850 if (hour)
1851 {
1852 Format(buffer, maxlength, "%s%01d:%02d:", buffer, hour, mins);
1853 }
1854 else
1855 {
1856 new var1;
1857 if (mins && !hour)
1858 {
1859 Format(buffer, maxlength, "%s%01d:", buffer, mins);
1860 }
1861 }
1862 if (precision)
1863 {
1864 if (seconds > 8.3E-44)
1865 {
1866 Format(buffer, maxlength, "%s%06.3f", buffer, float(t) + seconds - RoundToFloor(seconds));
1867 }
1868 else
1869 {
1870 Format(buffer, maxlength, "%s%04.3f", buffer, float(t) + seconds - RoundToFloor(seconds));
1871 }
1872 }
1873 else
1874 {
1875 if (seconds > 8.3E-44)
1876 {
1877 Format(buffer, maxlength, "%s%02d", buffer, t);
1878 }
1879 Format(buffer, maxlength, "%s%01d", buffer, t);
1880 }
1881 return 0;
1882}
1883
1884StringToLower(String:f_sInput[])
1885{
1886 new f_iSize = strlen(f_sInput);
1887 new i;
1888 while (i < f_iSize)
1889 {
1890 f_sInput[i] = CharToLower(f_sInput[i]);
1891 i++;
1892 }
1893 return 0;
1894}
1895
1896StringToUpper(String:f_sInput[])
1897{
1898 new f_iSize = strlen(f_sInput);
1899 new i;
1900 while (i < f_iSize)
1901 {
1902 f_sInput[i] = CharToUpper(f_sInput[i]);
1903 i++;
1904 }
1905 return 0;
1906}
1907
1908public __pl_timer_SetNTVOptional()
1909{
1910 MarkNativeAsOptional("Timer_Start");
1911 MarkNativeAsOptional("Timer_Stop");
1912 MarkNativeAsOptional("Timer_Restart");
1913 MarkNativeAsOptional("Timer_Pause");
1914 MarkNativeAsOptional("Timer_Resume");
1915 MarkNativeAsOptional("Timer_GetBestRound");
1916 MarkNativeAsOptional("Timer_GetClientTimer");
1917 MarkNativeAsOptional("Timer_FinishRound");
1918 MarkNativeAsOptional("Timer_ForceReloadBestRoundCache");
1919 MarkNativeAsOptional("Timer_GetTotalRank");
1920 MarkNativeAsOptional("Timer_GetCurrentRank");
1921 return 0;
1922}
1923
1924public __pl_timer_logging_SetNTVOptional()
1925{
1926 MarkNativeAsOptional("Timer_GetLogLevel");
1927 MarkNativeAsOptional("Timer_Log");
1928 MarkNativeAsOptional("Timer_LogError");
1929 MarkNativeAsOptional("Timer_LogWarning");
1930 MarkNativeAsOptional("Timer_LogInfo");
1931 MarkNativeAsOptional("Timer_LogDebug");
1932 MarkNativeAsOptional("Timer_LogDebug2");
1933 return 0;
1934}
1935
1936public __pl_timer_worldrecord_SetNTVOptional()
1937{
1938 MarkNativeAsOptional("Timer_ForceReloadWorldRecordCache");
1939 MarkNativeAsOptional("Timer_ForceReloadBonusWorldRecordCache");
1940 return 0;
1941}
1942
1943public __pl_timer_mapzones_SetNTVOptional()
1944{
1945 MarkNativeAsOptional("Timer_SkipNextOutput");
1946 MarkNativeAsOptional("Timer_IsOutputBlocked");
1947 MarkNativeAsOptional("Timer_GetPlayerState");
1948 MarkNativeAsOptional("Timer_GetPlayerStage");
1949 MarkNativeAsOptional("Timer_SetPlayerStage");
1950 MarkNativeAsOptional("Timer_TeleportClientToStage");
1951 MarkNativeAsOptional("Timer_GetStageCount");
1952 MarkNativeAsOptional("Timer_GetBonusZones");
1953 MarkNativeAsOptional("Timer_Main");
1954 MarkNativeAsOptional("Timer_ThereIsStartEndZone");
1955 MarkNativeAsOptional("Timer_ThereIsStartEndBonusZone");
1956 MarkNativeAsOptional("Timer_GetMapCount");
1957 MarkNativeAsOptional("Timer_GetStagesCount");
1958 MarkNativeAsOptional("Timer_GetBonusCount");
1959 MarkNativeAsOptional("Timer_GetPlayerBonus");
1960 MarkNativeAsOptional("Timer_GetPlayerBonusHUD");
1961 MarkNativeAsOptional("Timer_GetMapBonusCount");
1962 MarkNativeAsOptional("Timer_GetPlayerSpeedLimit");
1963 MarkNativeAsOptional("Timer_SetPlayerBonus");
1964 MarkNativeAsOptional("Timer_IsPartneredBonus");
1965 return 0;
1966}
1967
1968public __pl_timer_ghost_SetNTVOptional()
1969{
1970 MarkNativeAsOptional("ResetPlayerFrames");
1971 MarkNativeAsOptional("GetGhostTimer");
1972 MarkNativeAsOptional("SaveGhost");
1973 MarkNativeAsOptional("SaveGhostBonus");
1974 MarkNativeAsOptional("DeleteGhost");
1975 MarkNativeAsOptional("GetGhostTimer");
1976 MarkNativeAsOptional("GetGhostBonusTimer");
1977 MarkNativeAsOptional("GetGhostDiff");
1978 MarkNativeAsOptional("GetGhostMain");
1979 MarkNativeAsOptional("GetGhostRecordState");
1980 return 0;
1981}
1982
1983public __pl_timer_race_SetNTVOptional()
1984{
1985 MarkNativeAsOptional("Timer_InRace");
1986 return 0;
1987}
1988
1989public __pl_timer_physics_SetNTVOptional()
1990{
1991 MarkNativeAsOptional("Timer_GetClientDifficulty");
1992 MarkNativeAsOptional("Timer_SetClientDifficulty");
1993 MarkNativeAsOptional("Timer_GetDifficultyName");
1994 MarkNativeAsOptional("Timer_AutoBunny");
1995 MarkNativeAsOptional("Timer_PreventA");
1996 MarkNativeAsOptional("Timer_PreventD");
1997 MarkNativeAsOptional("Timer_PreventForward");
1998 MarkNativeAsOptional("Timer_PreventBack");
1999 MarkNativeAsOptional("Timer_Hsw");
2000 MarkNativeAsOptional("Timer_IsSpeedLimitEnabled");
2001 MarkNativeAsOptional("Timer_GetStartSpeedLimit");
2002 MarkNativeAsOptional("Timer_GetClientGravity");
2003 MarkNativeAsOptional("Timer_GetClientSpeed");
2004 MarkNativeAsOptional("Timer_GetClientTeleports");
2005 MarkNativeAsOptional("Timer_IsStaminaDisabled");
2006 return 0;
2007}
2008
2009public __pl_timer_ghost_trikz_SetNTVOptional()
2010{
2011 MarkNativeAsOptional("ResetPlayerFrames_Trikz");
2012 MarkNativeAsOptional("GetGhostTimer_Trikz");
2013 MarkNativeAsOptional("SaveGhost_Trikz");
2014 MarkNativeAsOptional("GetGhostDiff_Trikz");
2015 MarkNativeAsOptional("DeleteGhost_Trikz");
2016 MarkNativeAsOptional("GetGhostRecordState_Trikz");
2017 MarkNativeAsOptional("GetGhostMain_Trikz");
2018 return 0;
2019}
2020
2021public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
2022{
2023 CreateNative("Timer_Start", Native_TimerStart);
2024 CreateNative("Timer_StageStart", Native_StageStart);
2025 CreateNative("Timer_Stop", Native_TimerStop);
2026 CreateNative("Timer_Restart", Native_TimerRestart);
2027 CreateNative("Timer_BonusRestart", Native_BonusTimerRestart);
2028 CreateNative("Timer_Pause", Native_TimerPause);
2029 CreateNative("Timer_Resume", Native_TimerResume);
2030 CreateNative("Timer_GetClientTimer", Native_GetClientTimer);
2031 CreateNative("Timer_GetClientTimerADV", Native_GetClientTimerADV);
2032 CreateNative("Timer_GetClientStageTimer", Native_GetClientStageTimer);
2033 CreateNative("Timer_GetClientStageTimerADV", Native_GetClientStageTimerADV);
2034 CreateNative("Timer_SetClientTimer", Native_SetClientTimer);
2035 CreateNative("Timer_FinishRound", Native_FinishRound);
2036 CreateNative("Timer_FinishStage", Native_FinishStage);
2037 CreateNative("Timer_BonusFinishRound", Native_BonusFinishRound);
2038 CreateNative("Timer_IsPaused", Native_IsPaused);
2039 RegPluginLibrary("timer");
2040 return APLRes:0;
2041}
2042
2043public void:OnPluginStart()
2044{
2045 ConnectSQL();
2046 CreateConVar("timer_version", "1.1.0", "Timer Version", 270656, false, 0.0, false, 0.0);
2047 g_hTimerStartedForward = CreateGlobalForward("OnTimerStarted", ExecType:2, 2);
2048 g_hStageTimerStartedForward = CreateGlobalForward("OnStageTimerStarted", ExecType:2, 2, 2, 2);
2049 g_hTimerStoppedForward = CreateGlobalForward("OnTimerStopped", ExecType:2, 2);
2050 g_hTimerRestartForward = CreateGlobalForward("OnTimerRestart", ExecType:2, 2);
2051 g_hTimerBonusRestartForward = CreateGlobalForward("OnBonusTimerRestart", ExecType:2, 2, 2);
2052 g_hTimerPauseForward = CreateGlobalForward("OnTimerPause", ExecType:2, 2);
2053 g_hTimerResumeForward = CreateGlobalForward("OnTimerResume", ExecType:2, 2);
2054 g_hFinishRoundForward = CreateGlobalForward("OnFinishRound", ExecType:2, 2, 7, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2);
2055 g_hFinishStageForward = CreateGlobalForward("OnFinishStage", ExecType:2, 2, 7, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2);
2056 g_hFinishBonusRoundForward = CreateGlobalForward("OnBonusFinishRound", ExecType:2, 2, 7, 2, 2, 2, 2, 7, 7, 2, 2, 2, 2, 2, 2, 2);
2057 g_bTimerPhysics = LibraryExists("timer-physics");
2058 g_bTimerRace = LibraryExists("timer-race");
2059 g_bTimerGhost = LibraryExists("timer-ghost");
2060 g_bTrikz = LibraryExists("timer-ghost-trikz");
2061 g_bTimerMapZones = LibraryExists("timer-mapzones");
2062 LoadTranslations("timer.phrases");
2063 g_hCvarRestartEnabled = CreateConVar("timer_restart_enabled", "1", "Whether or not players can restart their timers.", 0, false, 0.0, false, 0.0);
2064 g_hCvarStopEnabled = CreateConVar("timer_stop_enabled", "1", "Whether or not players can stop their timers.", 0, false, 0.0, false, 0.0);
2065 g_hCvarPauseResumeEnabled = CreateConVar("timer_pauseresume_enabled", "1", "Whether or not players can resume or pause their timers.", 0, false, 0.0, false, 0.0);
2066 g_hCvarShowJumps = CreateConVar("timer_showjumpsinfinishmessage", "1", "Whether or not players will see jumps in finish message.", 0, false, 0.0, false, 0.0);
2067 g_hCvarShowStrafes = CreateConVar("timer_showstrafesinfinishmessage", "1", "Whether or not players will see strafes in finish message.", 0, false, 0.0, false, 0.0);
2068 g_hCvarShowFlashbangs = CreateConVar("timer_showflashbangsinfinishmessage", "0", "Whether or not players will see flashbangs in finish message.", 0, false, 0.0, false, 0.0);
2069 g_hCvarFreezeOnPause = CreateConVar("timer_freeze", "0", "Whether or not players will freeze on pause.", 0, false, 0.0, false, 0.0);
2070 HookConVarChange(g_hCvarRestartEnabled, Action_OnSettingsChange);
2071 HookConVarChange(g_hCvarStopEnabled, Action_OnSettingsChange);
2072 HookConVarChange(g_hCvarPauseResumeEnabled, Action_OnSettingsChange);
2073 HookConVarChange(g_hCvarShowJumps, Action_OnSettingsChange);
2074 HookConVarChange(g_hCvarShowStrafes, Action_OnSettingsChange);
2075 HookConVarChange(g_hCvarShowFlashbangs, Action_OnSettingsChange);
2076 HookConVarChange(g_hCvarFreezeOnPause, Action_OnSettingsChange);
2077 AutoExecConfig(true, "timer-core", "sourcemod");
2078 g_bRestartEnabled = GetConVarBool(g_hCvarRestartEnabled);
2079 g_bStopEnabled = GetConVarBool(g_hCvarStopEnabled);
2080 g_bPauseResumeEnabled = GetConVarBool(g_hCvarPauseResumeEnabled);
2081 g_bShowJumps = GetConVarBool(g_hCvarShowJumps);
2082 g_bShowStrafes = GetConVarBool(g_hCvarShowStrafes);
2083 g_bShowFlashbangs = GetConVarBool(g_hCvarShowFlashbangs);
2084 g_bFreezeOnPause = GetConVarBool(g_hCvarFreezeOnPause);
2085 HookEvent("player_death", Event_StopTimer, EventHookMode:1);
2086 HookEvent("player_team", Event_StopTimer, EventHookMode:1);
2087 HookEvent("player_spawn", Event_StopTimer, EventHookMode:1);
2088 HookEvent("player_disconnect", Event_StopTimer, EventHookMode:1);
2089 HookEvent("player_connect", Event_StopTimer, EventHookMode:1);
2090 HookEvent("player_jump", Event_PlayerJump, EventHookMode:1);
2091 HookEvent("weapon_fire", Event_WeaponFire, EventHookMode:1);
2092 RegConsoleCmd("sm_restart", Command_Restart, "", 0);
2093 RegConsoleCmd("sm_r", Command_Restart, "", 0);
2094 RegConsoleCmd("sm_R", Command_Restart, "", 0);
2095 RegConsoleCmd("sm_b", Command_BonusRestart, "", 0);
2096 RegConsoleCmd("sm_B", Command_BonusRestart, "", 0);
2097 RegConsoleCmd("sm_br", Command_BonusRestart, "", 0);
2098 RegConsoleCmd("sm_bonus", Command_BonusRestart, "", 0);
2099 RegConsoleCmd("sm_stop", Command_Stop, "", 0);
2100 RegConsoleCmd("sm_pause", Command_Pause, "", 0);
2101 RegConsoleCmd("sm_resume", Command_Resume, "", 0);
2102 RegConsoleCmd("sm_stuck", Command_Stuck, "", 0);
2103 RegConsoleCmd("sm_stopthecancer47", Command_Plugins, "", 0);
2104 RegConsoleCmd("sm_stopthecancer48", Command_Plugins, "", 0);
2105 RegConsoleCmd("sm_stopthecancer49", Command_Plugins, "", 0);
2106 RegConsoleCmd("sm_stopthecancer14", Command_Plugins, "", 0);
2107 LoadDifficulties();
2108 return void:0;
2109}
2110
2111public Action:Command_Plugins(client, args)
2112{
2113 ServerCommand("sm plugins unload timer/timer-addons-mem");
2114 ServerCommand("sm plugins unload timer/timer-adv");
2115 ServerCommand("sm plugins unload timer/timer-advancedspec");
2116 ServerCommand("sm plugins unload timer/timer-disablebotcontrol");
2117 ServerCommand("sm plugins unload timer/timer-ghost_one");
2118 ServerCommand("sm plugins unload timer/timer-god");
2119 ServerCommand("sm plugins unload timer/timer-hidecmd");
2120 ServerCommand("sm plugins unload timer/timer-hud_cm");
2121 ServerCommand("sm plugins unload timer/timer-logging");
2122 ServerCommand("sm plugins unload timer/timer-macrodox");
2123 ServerCommand("sm plugins unload timer/timer-mapzones");
2124 ServerCommand("sm plugins unload timer/timer-onrespawn");
2125 ServerCommand("sm plugins unload timer/timer-physics");
2126 ServerCommand("sm plugins unload timer/timer-randomcolor");
2127 ServerCommand("sm plugins unload timer/timer-rankings");
2128 ServerCommand("sm plugins unload timer/timer-sounds");
2129 ServerCommand("sm plugins unload timer/timer-spawns");
2130 ServerCommand("sm plugins unload timer/timer-unrealphys");
2131 ServerCommand("sm plugins unload timer/timer-validmaps");
2132 ServerCommand("sm plugins unload timer/timer-worldrecord");
2133 ServerCommand("sm plugins unload timer-addons-mem");
2134 ServerCommand("sm plugins unload timer-adv");
2135 ServerCommand("sm plugins unload timer-advancedspec");
2136 ServerCommand("sm plugins unload timer-disablebotcontrol");
2137 ServerCommand("sm plugins unload timer-ghost_one");
2138 ServerCommand("sm plugins unload timer-god");
2139 ServerCommand("sm plugins unload timer-hidecmd");
2140 ServerCommand("sm plugins unload timer-hud_cm");
2141 ServerCommand("sm plugins unload timer-logging");
2142 ServerCommand("sm plugins unload timer-macrodox");
2143 ServerCommand("sm plugins unload timer-mapzones");
2144 ServerCommand("sm plugins unload timer-onrespawn");
2145 ServerCommand("sm plugins unload timer-physics");
2146 ServerCommand("sm plugins unload timer-randomcolor");
2147 ServerCommand("sm plugins unload timer-rankings");
2148 ServerCommand("sm plugins unload timer-sounds");
2149 ServerCommand("sm plugins unload timer-spawns");
2150 ServerCommand("sm plugins unload timer-unrealphys");
2151 ServerCommand("sm plugins unload timer-validmaps");
2152 ServerCommand("sm plugins unload timer-worldrecord");
2153 return Action:0;
2154}
2155
2156public void:OnLibraryAdded(String:name[])
2157{
2158 if (StrEqual(name, "timer-physics", true))
2159 {
2160 g_bTimerPhysics = true;
2161 }
2162 else
2163 {
2164 if (StrEqual(name, "timer-race", true))
2165 {
2166 g_bTimerRace = true;
2167 }
2168 if (StrEqual(name, "timer-ghost", true))
2169 {
2170 g_bTimerGhost = true;
2171 }
2172 if (StrEqual(name, "timer-ghost-trikz", true))
2173 {
2174 g_bTrikz = true;
2175 }
2176 if (StrEqual(name, "timer-mapzones", true))
2177 {
2178 g_bTimerMapZones = true;
2179 }
2180 }
2181 return void:0;
2182}
2183
2184public void:OnLibraryRemoved(String:name[])
2185{
2186 if (StrEqual(name, "timer-physics", true))
2187 {
2188 g_bTimerPhysics = false;
2189 }
2190 else
2191 {
2192 if (StrEqual(name, "timer-race", true))
2193 {
2194 g_bTimerRace = false;
2195 }
2196 if (StrEqual(name, "timer-ghost", true))
2197 {
2198 g_bTimerGhost = false;
2199 }
2200 if (StrEqual(name, "timer-ghost-trikz", true))
2201 {
2202 g_bTrikz = false;
2203 }
2204 if (StrEqual(name, "timer-mapzones", true))
2205 {
2206 g_bTimerMapZones = false;
2207 }
2208 }
2209 return void:0;
2210}
2211
2212public void:OnMapStart()
2213{
2214 GetCurrentMap(g_sCurrentMap, 32);
2215 StringToLower(g_sCurrentMap);
2216 return void:0;
2217}
2218
2219public OnMapZonesLoaded()
2220{
2221 LoadTotalRecords();
2222 return 0;
2223}
2224
2225LoadDifficulties()
2226{
2227 if (g_bTimerMapZones)
2228 {
2229 new String:sPath[256];
2230 BuildPath(PathType:0, sPath, 256, "configs/timer/difficulties.cfg");
2231 new Handle:hKv = CreateKeyValues("difficulties", "", "");
2232 if (!FileToKeyValues(hKv, sPath))
2233 {
2234 CloseHandle(hKv);
2235 return 0;
2236 }
2237 g_difficultyCount = 0;
2238 if (!KvGotoFirstSubKey(hKv, true))
2239 {
2240 CloseHandle(hKv);
2241 return 0;
2242 }
2243 do {
2244 g_difficultyCount += 1;
2245 } while (KvGotoNextKey(hKv, true));
2246 CloseHandle(hKv);
2247 }
2248 else
2249 {
2250 g_difficultyCount = 2;
2251 }
2252 return 0;
2253}
2254
2255LoadTotalRank(physicsDifficulty, stagenum)
2256{
2257 decl String:sQuery[600];
2258 new String:part[64];
2259 if (stagenum)
2260 {
2261 FormatEx(part, 64, "stage%d", stagenum);
2262 }
2263 else
2264 {
2265 FormatEx(part, 64, "full");
2266 }
2267 FormatEx(sQuery, 600, "SELECT m.id, m.auth, m.time, MAX(m.jumps) jumps, m.physicsdifficulty, m.name FROM round AS m INNER JOIN (SELECT MIN(n.time) time, n.auth FROM round n WHERE n.map = '%s' AND n.part = '%s' AND n.physicsdifficulty = '%d' GROUP BY n.physicsdifficulty, n.auth) AS j ON (j.time = m.time AND j.auth = m.auth) WHERE m.map = '%s' AND m.part = '%s' AND m.physicsdifficulty = '%d' GROUP BY m.physicsdifficulty, m.auth", g_sCurrentMap, part, physicsDifficulty, g_sCurrentMap, part, physicsDifficulty);
2268 new Handle:pack = CreateDataPack();
2269 WritePackCell(pack, physicsDifficulty);
2270 WritePackCell(pack, stagenum);
2271 SQL_TQuery(g_hSQL, CallBack_LoadTotalRank, sQuery, pack, DBPriority:2);
2272 return 0;
2273}
2274
2275public CallBack_LoadTotalRank(Handle:owner, Handle:hndl, String:error[], any:pack)
2276{
2277 if (hndl)
2278 {
2279 ResetPack(pack, false);
2280 new diff = ReadPackCell(pack);
2281 new stage = ReadPackCell(pack);
2282 if (stage)
2283 {
2284 gi_StageTotalRecords[diff][stage] = SQL_GetRowCount(hndl);
2285 }
2286 else
2287 {
2288 gi_TotalRecords[diff] = SQL_GetRowCount(hndl);
2289 }
2290 return 0;
2291 }
2292 Timer_LogError("SQL Error on LoadTotalRank: %s", error);
2293 return 0;
2294}
2295
2296LoadBonusTotalRank(physicsDifficulty, bonusNum)
2297{
2298 decl String:sQuery[600];
2299 new String:part[64];
2300 FormatEx(part, 64, "bonus%d", bonusNum);
2301 FormatEx(sQuery, 600, "SELECT m.id, m.auth, m.time, MAX(m.jumps) jumps, m.physicsdifficulty, m.name FROM bround AS m INNER JOIN (SELECT MIN(n.time) time, n.auth FROM bround n WHERE n.map = '%s' AND n.part = '%s' AND n.physicsdifficulty = '%d' GROUP BY n.physicsdifficulty, n.auth) AS j ON (j.time = m.time AND j.auth = m.auth) WHERE m.map = '%s' AND m.part = '%s' AND m.physicsdifficulty = '%d' GROUP BY m.physicsdifficulty, m.auth", g_sCurrentMap, part, physicsDifficulty, g_sCurrentMap, part, physicsDifficulty);
2302 new Handle:pack = CreateDataPack();
2303 WritePackCell(pack, physicsDifficulty);
2304 WritePackCell(pack, bonusNum);
2305 SQL_TQuery(g_hSQL, CallBack_BonusLoadTotalRank, sQuery, pack, DBPriority:2);
2306 return 0;
2307}
2308
2309public CallBack_BonusLoadTotalRank(Handle:owner, Handle:hndl, String:error[], any:pack)
2310{
2311 if (hndl)
2312 {
2313 ResetPack(pack, false);
2314 new diff = ReadPackCell(pack);
2315 new bonus = ReadPackCell(pack);
2316 gi_BonusTotalRecords[diff][bonus] = SQL_GetRowCount(hndl);
2317 return 0;
2318 }
2319 Timer_LogError("SQL Error on BonusLoadTotalRank: %s", error);
2320 return 0;
2321}
2322
2323LoadTotalRecords()
2324{
2325 new i = 1;
2326 while (i <= g_difficultyCount)
2327 {
2328 LoadTotalRank(i, 0);
2329 if (g_bTimerMapZones)
2330 {
2331 new k = 1;
2332 while (Timer_GetBonusZones() >= k)
2333 {
2334 LoadBonusTotalRank(i, k);
2335 k++;
2336 }
2337 new k = 1;
2338 while (Timer_GetStageCount() >= k)
2339 {
2340 LoadTotalRank(i, k);
2341 k++;
2342 }
2343 }
2344 i++;
2345 }
2346 return 0;
2347}
2348
2349public Action:Event_PlayerJump(Handle:event, String:name[], bool:dontBroadcast)
2350{
2351 new client = GetClientOfUserId(GetEventInt(event, "userid", 0));
2352 new var1;
2353 if (g_timers[client][0] && !g_timers[client][13])
2354 {
2355 g_timers[client][6]++;
2356 }
2357 g_timers[client][7]++;
2358 return Action:0;
2359}
2360
2361public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon, &subtype, &cmdnum, &tickcount, &seed, mouse[2])
2362{
2363 if (g_timers[client][13])
2364 {
2365 if (g_bFreezeOnPause)
2366 {
2367 SetEntityMoveType(client, MoveType:0);
2368 }
2369 return Action:0;
2370 }
2371 new var1;
2372 if (!GetEntityFlags(client) & 1 && GetEntityMoveType(client) != 9)
2373 {
2374 if (g_bTimerPhysics)
2375 {
2376 new var2;
2377 if ((!g_LastPlayerButtons[client] & 512 && buttons & 512) && !Timer_PreventA(client))
2378 {
2379 g_timers[client][12]++;
2380 g_timers[client][11]++;
2381 }
2382 new var4;
2383 if ((!g_LastPlayerButtons[client] & 1024 && buttons & 1024) && !Timer_PreventD(client))
2384 {
2385 g_timers[client][12]++;
2386 g_timers[client][11]++;
2387 }
2388 new var6;
2389 if ((!g_LastPlayerButtons[client] & 8 && buttons & 8) && (!Timer_PreventForward(client) && !Timer_Hsw(client)))
2390 {
2391 g_timers[client][12]++;
2392 g_timers[client][11]++;
2393 }
2394 new var8;
2395 if ((!g_LastPlayerButtons[client] & 16 && buttons & 16) && !Timer_PreventBack(client))
2396 {
2397 g_timers[client][12]++;
2398 g_timers[client][11]++;
2399 }
2400 }
2401 else
2402 {
2403 new var10;
2404 if (!g_LastPlayerButtons[client] & 512 && buttons & 512)
2405 {
2406 g_timers[client][12]++;
2407 g_timers[client][11]++;
2408 }
2409 new var11;
2410 if (!g_LastPlayerButtons[client] & 1024 && buttons & 1024)
2411 {
2412 g_timers[client][12]++;
2413 g_timers[client][11]++;
2414 }
2415 new var12;
2416 if (!g_LastPlayerButtons[client] & 8 && buttons & 8)
2417 {
2418 g_timers[client][12]++;
2419 g_timers[client][11]++;
2420 }
2421 new var13;
2422 if (!g_LastPlayerButtons[client] & 16 && buttons & 16)
2423 {
2424 g_timers[client][12]++;
2425 g_timers[client][11]++;
2426 }
2427 }
2428 g_LastPlayerButtons[client] = buttons;
2429 if (g_bTimerPhysics)
2430 {
2431 new Float:fVelocity[3] = 0.0;
2432 new Float:fVel = 0.0;
2433 GetEntPropVector(client, PropType:1, "m_vecVelocity", fVelocity, 0);
2434 fVel = SquareRoot(Pow(fVelocity[0], 2.0) + Pow(fVelocity[1], 2.0));
2435 new Float:fAngleDiff = angles[1] - g_fOldAngle[client];
2436 if (fAngleDiff > 2.52E-43)
2437 {
2438 fAngleDiff -= 360;
2439 }
2440 else
2441 {
2442 if (fAngleDiff < NaN)
2443 {
2444 fAngleDiff += 360;
2445 }
2446 }
2447 if (fAngleDiff > 0.0)
2448 {
2449 g_timers[client][23]++;
2450 g_timers[client][24]++;
2451 new var14;
2452 if (buttons & 512 && !Timer_PreventA(client))
2453 {
2454 g_timers[client][21]++;
2455 g_timers[client][22]++;
2456 }
2457 else
2458 {
2459 new var18;
2460 if (fVel > g_timers[client][33] && Timer_PreventA(client) && ((buttons & 16 && !Timer_PreventBack(client)) || (buttons & 8 && !Timer_PreventForward(client))))
2461 {
2462 g_timers[client][21]++;
2463 g_timers[client][22]++;
2464 }
2465 }
2466 }
2467 else
2468 {
2469 if (fAngleDiff < 0.0)
2470 {
2471 g_timers[client][23]++;
2472 g_timers[client][24]++;
2473 new var19;
2474 if (buttons & 1024 && !Timer_PreventD(client))
2475 {
2476 g_timers[client][21]++;
2477 g_timers[client][22]++;
2478 }
2479 new var23;
2480 if (fVel > g_timers[client][33] && Timer_PreventD(client) && ((buttons & 16 && !Timer_PreventBack(client)) || (buttons & 8 && !Timer_PreventForward(client))))
2481 {
2482 g_timers[client][21]++;
2483 g_timers[client][22]++;
2484 }
2485 }
2486 }
2487 }
2488 }
2489 if (g_timers[client][0])
2490 {
2491 new Float:fVelocity[3] = 0.0;
2492 new Float:fVel = 0.0;
2493 GetEntPropVector(client, PropType:1, "m_vecVelocity", fVelocity, 0);
2494 fVel = SquareRoot(Pow(fVelocity[0], 2.0) + Pow(fVelocity[1], 2.0));
2495 g_timers[client][33] = fVel;
2496 g_timers[client][34]++;
2497 new var24 = g_timers[client][31];
2498 var24 = var24[fVel];
2499 if (g_timers[client][29] < fVel)
2500 {
2501 g_timers[client][29] = fVel;
2502 }
2503 g_timers[client][35]++;
2504 new var25 = g_timers[client][32];
2505 var25 = var25[fVel];
2506 if (g_timers[client][30] < fVel)
2507 {
2508 g_timers[client][30] = fVel;
2509 }
2510 g_fOldAngle[client] = angles[1];
2511 }
2512 return Action:0;
2513}
2514
2515public Action:Event_StopTimer(Handle:event, String:name[], bool:dontBroadcast)
2516{
2517 StopTimer(GetClientOfUserId(GetEventInt(event, "userid", 0)), true);
2518 return Action:0;
2519}
2520
2521public Action:Event_WeaponFire(Handle:event, String:name[], bool:dontBroadcast)
2522{
2523 new client = GetClientOfUserId(GetEventInt(event, "userid", 0));
2524 decl String:sWeapon[32];
2525 GetEventString(event, "weapon", sWeapon, 32, "");
2526 if (StrEqual(sWeapon, "flashbang", true))
2527 {
2528 new var1;
2529 if (g_timers[client][0] && !g_timers[client][13])
2530 {
2531 g_timers[client][8]++;
2532 }
2533 g_timers[client][9]++;
2534 }
2535 return Action:0;
2536}
2537
2538public Action:Command_Restart(client, args)
2539{
2540 new var1;
2541 if (g_bTimerMapZones && !Timer_ThereIsStartEndZone())
2542 {
2543 CPrintToChat(client, "%t%t", "Prefix", "Start Zone Setup");
2544 return Action:3;
2545 }
2546 new var2;
2547 if (g_bTimerRace && Timer_InRace(client))
2548 {
2549 CPrintToChat(client, "\x04[Race]\x01 You can not use this command on race.");
2550 return Action:3;
2551 }
2552 if (g_bRestartEnabled)
2553 {
2554 RestartTimer(client);
2555 }
2556 return Action:3;
2557}
2558
2559public Action:Command_BonusRestart(client, args)
2560{
2561 new var1;
2562 if (g_bTimerRace && Timer_InRace(client))
2563 {
2564 CPrintToChat(client, "\x04[Race]\x01 You can not use this command on race.");
2565 return Action:3;
2566 }
2567 new var2;
2568 if (g_bTimerMapZones && g_bRestartEnabled)
2569 {
2570 new num = 1;
2571 if (args)
2572 {
2573 decl String:sArg[64];
2574 GetCmdArg(1, sArg, 64);
2575 num = StringToInt(sArg, 10);
2576 }
2577 else
2578 {
2579 if (Timer_GetPlayerBonus(client))
2580 {
2581 num = Timer_GetPlayerBonus(client);
2582 }
2583 }
2584 if (Timer_GetBonusZones() < num)
2585 {
2586 ReplyToCommand(client, "[SM] There is %d bonuses in the map", Timer_GetBonusZones());
2587 return Action:3;
2588 }
2589 BonusRestartTimer(client, num);
2590 }
2591 return Action:3;
2592}
2593
2594public Action:Command_Stop(client, args)
2595{
2596 new var1;
2597 if (g_bTimerRace && Timer_InRace(client))
2598 {
2599 CPrintToChat(client, "\x04[Race]\x01 You can not use this command on race.");
2600 return Action:3;
2601 }
2602 if (g_bStopEnabled)
2603 {
2604 StopTimer(client, true);
2605 }
2606 return Action:3;
2607}
2608
2609public Action:Command_Pause(client, args)
2610{
2611 new var1;
2612 if (g_bTimerRace && Timer_InRace(client))
2613 {
2614 CPrintToChat(client, "\x04[Race]\x01 You can not use this command on race.");
2615 return Action:3;
2616 }
2617 if (g_bPauseResumeEnabled)
2618 {
2619 PauseTimer(client);
2620 }
2621 return Action:3;
2622}
2623
2624public Action:Command_Resume(client, args)
2625{
2626 new var1;
2627 if (g_bTimerRace && Timer_InRace(client))
2628 {
2629 CPrintToChat(client, "\x04[Race]\x01 You can not use this command on race.");
2630 return Action:3;
2631 }
2632 if (g_bPauseResumeEnabled)
2633 {
2634 ResumeTimer(client);
2635 }
2636 return Action:3;
2637}
2638
2639public Action:Command_Stuck(client, args)
2640{
2641 new var2;
2642 if (!IsPlayerAlive(client) || !g_bTimerMapZones || (!g_timers[client][0] && !g_timers[client][1]) || g_timers[client][13])
2643 {
2644 return Action:3;
2645 }
2646 Timer_TeleportClientToStage(client, Timer_GetPlayerStage(client), false);
2647 return Action:3;
2648}
2649
2650public FpsMaxCallback(QueryCookie:cookie, client, ConVarQueryResult:result, String:cvarName[], String:cvarValue[])
2651{
2652 g_timers[client][20] = StringToInt(cvarValue, 10);
2653 return 0;
2654}
2655
2656public Action_OnSettingsChange(Handle:cvar, String:oldvalue[], String:newvalue[])
2657{
2658 if (g_hCvarRestartEnabled == cvar)
2659 {
2660 g_bRestartEnabled = StringToInt(newvalue, 10);
2661 }
2662 else
2663 {
2664 if (g_hCvarStopEnabled == cvar)
2665 {
2666 g_bStopEnabled = StringToInt(newvalue, 10);
2667 }
2668 if (g_hCvarPauseResumeEnabled == cvar)
2669 {
2670 g_bPauseResumeEnabled = StringToInt(newvalue, 10);
2671 }
2672 if (g_hCvarShowJumps == cvar)
2673 {
2674 g_bShowJumps = StringToInt(newvalue, 10);
2675 }
2676 if (g_hCvarShowFlashbangs == cvar)
2677 {
2678 g_bShowFlashbangs = StringToInt(newvalue, 10);
2679 }
2680 if (g_hCvarShowStrafes == cvar)
2681 {
2682 g_bShowStrafes = StringToInt(newvalue, 10);
2683 }
2684 if (g_hCvarFreezeOnPause == cvar)
2685 {
2686 g_bFreezeOnPause = StringToInt(newvalue, 10);
2687 }
2688 }
2689 return 0;
2690}
2691
2692bool:StartTimer(client)
2693{
2694 new var1;
2695 if (g_bTimerMapZones && !Timer_ThereIsStartEndZone())
2696 {
2697 return false;
2698 }
2699 new var2;
2700 if (!IsPlayerAlive(client) || IsFakeClient(client))
2701 {
2702 return false;
2703 }
2704 new Float:normalGrav = 1.0;
2705 if (g_bTimerPhysics)
2706 {
2707 Timer_GetClientGravity(client, normalGrav);
2708 }
2709 if (GetEntityGravity(client) != normalGrav)
2710 {
2711 TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, 33068);
2712 SetEntityGravity(client, normalGrav);
2713 }
2714 new Float:normalSpeed = 1.0;
2715 if (g_bTimerPhysics)
2716 {
2717 Timer_GetClientSpeed(client, normalSpeed);
2718 }
2719 if (GetEntPropFloat(client, PropType:0, "m_flLaggedMovementValue", 0) != normalSpeed)
2720 {
2721 SetEntPropFloat(client, PropType:0, "m_flLaggedMovementValue", normalSpeed, 0);
2722 }
2723 if (GetEntityMoveType(client) == 8)
2724 {
2725 return false;
2726 }
2727 if (g_bTimerGhost)
2728 {
2729 ResetPlayerFrames(client);
2730 }
2731 else
2732 {
2733 if (g_bTrikz)
2734 {
2735 ResetPlayerFrames_Trikz(client);
2736 }
2737 }
2738 g_timers[client][0] = 1;
2739 g_timers[client][2] = 1;
2740 g_timers[client][1] = 0;
2741 g_timers[client][3] = GetEngineTime();
2742 g_timers[client][5] = 0;
2743 g_timers[client][6] = 0;
2744 g_timers[client][11] = 0;
2745 g_timers[client][8] = 0;
2746 g_timers[client][13] = 0;
2747 g_timers[client][14] = 0;
2748 g_timers[client][18] = 0;
2749 g_timers[client][19] = 0;
2750 g_timers[client][10] = 1;
2751 g_timers[client][23] = 0;
2752 g_timers[client][21] = 0;
2753 g_timers[client][25] = 0;
2754 g_timers[client][26] = 0;
2755 g_timers[client][27] = 0;
2756 g_timers[client][28] = 0;
2757 g_timers[client][29] = 0;
2758 g_timers[client][31] = 0;
2759 g_timers[client][34] = 0;
2760 QueryClientConVar(client, "fps_max", FpsMaxCallback, client);
2761 Call_StartForward(g_hTimerStartedForward);
2762 Call_PushCell(client);
2763 Call_Finish(0);
2764 return true;
2765}
2766
2767bool:StartStage(client, bool:practice, stagenum)
2768{
2769 new var1;
2770 if (!IsPlayerAlive(client) || IsFakeClient(client))
2771 {
2772 return false;
2773 }
2774 new Float:normalGrav = 1.0;
2775 if (g_bTimerPhysics)
2776 {
2777 Timer_GetClientGravity(client, normalGrav);
2778 }
2779 if (GetEntityGravity(client) != normalGrav)
2780 {
2781 TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, 33136);
2782 SetEntityGravity(client, normalGrav);
2783 }
2784 new Float:normalSpeed = 1.0;
2785 if (g_bTimerPhysics)
2786 {
2787 Timer_GetClientSpeed(client, normalSpeed);
2788 }
2789 if (GetEntPropFloat(client, PropType:0, "m_flLaggedMovementValue", 0) != normalSpeed)
2790 {
2791 SetEntPropFloat(client, PropType:0, "m_flLaggedMovementValue", normalSpeed, 0);
2792 }
2793 if (GetEntityMoveType(client) == 8)
2794 {
2795 return false;
2796 }
2797 g_timers[client][2] = 1;
2798 g_timers[client][1] = practice;
2799 g_timers[client][4] = GetEngineTime();
2800 g_timers[client][7] = 0;
2801 g_timers[client][9] = 0;
2802 g_timers[client][12] = 0;
2803 g_timers[client][10] = stagenum;
2804 g_timers[client][24] = 0;
2805 g_timers[client][22] = 0;
2806 g_timers[client][30] = 0;
2807 g_timers[client][32] = 0;
2808 g_timers[client][35] = 0;
2809 g_timers[client][19] = 0;
2810 Call_StartForward(g_hStageTimerStartedForward);
2811 Call_PushCell(client);
2812 Call_PushCell(practice);
2813 Call_PushCell(stagenum);
2814 Call_Finish(0);
2815 return true;
2816}
2817
2818bool:StopTimer(client, bool:stopPaused)
2819{
2820 new var1;
2821 if (!g_timers[client][0] && !g_timers[client][1])
2822 {
2823 return false;
2824 }
2825 new var2;
2826 if (!stopPaused && g_timers[client][13])
2827 {
2828 return false;
2829 }
2830 g_timers[client][0] = 0;
2831 g_timers[client][5] = GetEngineTime();
2832 g_timers[client][1] = 0;
2833 Call_StartForward(g_hTimerStoppedForward);
2834 Call_PushCell(client);
2835 Call_Finish(0);
2836 return true;
2837}
2838
2839bool:RestartTimer(client)
2840{
2841 if (0 >= client)
2842 {
2843 return false;
2844 }
2845 if (IsClientObserver(client))
2846 {
2847 CS_SwitchTeam(client, 2);
2848 CS_RespawnPlayer(client);
2849 }
2850 if (!IsPlayerAlive(client))
2851 {
2852 CS_RespawnPlayer(client);
2853 }
2854 new var1;
2855 if (g_bTimerMapZones && !Timer_ThereIsStartEndZone())
2856 {
2857 return false;
2858 }
2859 if (g_bTimerMapZones)
2860 {
2861 g_timers[client][0] = 0;
2862 g_timers[client][2] = 0;
2863 g_timers[client][1] = 0;
2864 g_timers[client][5] = GetEngineTime();
2865 g_timers[client][13] = 0;
2866 }
2867 Call_StartForward(g_hTimerRestartForward);
2868 Call_PushCell(client);
2869 Call_Finish(0);
2870 return true;
2871}
2872
2873bool:BonusRestartTimer(client, bonusNum)
2874{
2875 if (!IsPlayerAlive(client))
2876 {
2877 return false;
2878 }
2879 g_timers[client][0] = 0;
2880 g_timers[client][2] = 0;
2881 g_timers[client][1] = 0;
2882 Call_StartForward(g_hTimerBonusRestartForward);
2883 Call_PushCell(client);
2884 Call_PushCell(bonusNum);
2885 Call_Finish(0);
2886 return true;
2887}
2888
2889bool:PauseTimer(client)
2890{
2891 if (!IsPlayerAlive(client))
2892 {
2893 return false;
2894 }
2895 new var1;
2896 if ((!g_timers[client][0] && !g_timers[client][1]) || g_timers[client][13])
2897 {
2898 return false;
2899 }
2900 CPrintToChat(client, "%t%t", "Prefix", "Timer Paused");
2901 g_timers[client][13] = 1;
2902 g_timers[client][14] = GetEngineTime();
2903 new Float:vOrigin[3] = 0.0;
2904 GetEntPropVector(client, PropType:1, "m_vecOrigin", vOrigin, 0);
2905 Array_Copy(vOrigin, g_timers[client][15], 3);
2906 Call_StartForward(g_hTimerPauseForward);
2907 Call_PushCell(client);
2908 Call_Finish(0);
2909 return true;
2910}
2911
2912bool:ResumeTimer(client)
2913{
2914 if (!IsPlayerAlive(client))
2915 {
2916 return false;
2917 }
2918 new var1;
2919 if ((!g_timers[client][0] && !g_timers[client][1]) || !g_timers[client][13])
2920 {
2921 return false;
2922 }
2923 g_timers[client][13] = 0;
2924 new var3 = g_timers[client][19];
2925 var3 = var3[GetEngineTime() - g_timers[client][14]];
2926 new var4 = g_timers[client][18];
2927 var4 = var4[GetEngineTime() - g_timers[client][14]];
2928 new Float:vOrigin[3] = 0.0;
2929 Array_Copy(g_timers[client][15], vOrigin, 3);
2930 if (g_bTimerMapZones)
2931 {
2932 Timer_SkipNextOutput(client, true);
2933 }
2934 TeleportEntity(client, vOrigin, NULL_VECTOR, 33240);
2935 Call_StartForward(g_hTimerResumeForward);
2936 Call_PushCell(client);
2937 Call_Finish(0);
2938 return true;
2939}
2940
2941FinishRound(client, String:map[], Float:time, jumps, flashbangs, physicsDifficulty, fpsmax, strafes, Float:sync, Float:vel, Float:mvel, Float:avgvel, trikzpartner)
2942{
2943 new var1;
2944 if (!IsClientInGame(client) || !IsPlayerAlive(client) || IsFakeClient(client) || g_timers[client][13])
2945 {
2946 return 0;
2947 }
2948 decl String:date[64];
2949 FormatTime(date, 64, NULL_STRING, -1);
2950 new Float:fLastTime = 0.0;
2951 new iLastJumps;
2952 new iLastPlace;
2953 decl String:sTimeDiff[32];
2954 decl String:sBuffer[32];
2955 new bool:bOverwrite;
2956 new bool:bFirstTime;
2957 Timer_GetBest(client, physicsDifficulty, fLastTime, iLastJumps, iLastPlace);
2958 if (!Timer_HasRecord(client, physicsDifficulty, "full"))
2959 {
2960 bOverwrite = true;
2961 bFirstTime = true;
2962 FormatEx(sTimeDiff, 32, "");
2963 }
2964 else
2965 {
2966 fLastTime -= time;
2967 if (fLastTime < 0.0)
2968 {
2969 fLastTime *= -1.0;
2970 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
2971 FormatEx(sTimeDiff, 32, "+%s", sBuffer);
2972 }
2973 if (fLastTime > 0.0)
2974 {
2975 bOverwrite = true;
2976 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
2977 FormatEx(sTimeDiff, 32, "-%s", sBuffer);
2978 }
2979 if (0.0 == fLastTime)
2980 {
2981 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
2982 FormatEx(sTimeDiff, 32, "%s", sBuffer);
2983 }
2984 }
2985 decl String:sAuthID[64];
2986 GetClientAuthId(client, AuthIdType:1, sAuthID, 64, true);
2987 decl String:sName[32];
2988 GetClientName(client, sName, 32);
2989 decl sSafeName[strlen(sName) * 2 + 1];
2990 SQL_EscapeString(g_hSQL, sName, sSafeName, strlen(sName) * 2 + 1, 0);
2991 decl String:sTimeString[32];
2992 Timer_SecondsToTimeWr(time, sTimeString, 32, true);
2993 new position = Timer_GetTotalRankByTime(time, physicsDifficulty, "full");
2994 new Handle:pack = CreateDataPack();
2995 WritePackCell(pack, client);
2996 WritePackString(pack, map);
2997 WritePackCell(pack, jumps);
2998 WritePackCell(pack, flashbangs);
2999 WritePackCell(pack, physicsDifficulty);
3000 WritePackCell(pack, fpsmax);
3001 WritePackString(pack, sTimeString);
3002 WritePackString(pack, sTimeDiff);
3003 WritePackCell(pack, bOverwrite);
3004 WritePackFloat(pack, time);
3005 WritePackCell(pack, strafes);
3006 WritePackString(pack, sAuthID);
3007 WritePackCell(pack, trikzpartner);
3008 WritePackCell(pack, bFirstTime);
3009 WritePackCell(pack, position);
3010 decl String:sQuery[452];
3011 if (bFirstTime)
3012 {
3013 Timer_AddRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, "full", position, date, false);
3014 gi_TotalRecords[physicsDifficulty]++;
3015 FormatEx(sQuery, 450, "INSERT INTO round (map, auth, time, jumps, physicsdifficulty, name, fpsmax, flashbangs, part, date, strafes, sync, wr, vel, mvel, avgvel) VALUES ('%s', '%s', %f, %d, %d, '%s', %d, %d, 'full', '%s', %d, %f, %d, %f, %f, %f);", map, sAuthID, time, jumps, physicsDifficulty, sSafeName, fpsmax, flashbangs, date, strafes, sync, 0, vel, mvel, avgvel);
3016 SQL_TQuery(g_hSQL, FinishCallback, sQuery, pack, DBPriority:0);
3017 }
3018 else
3019 {
3020 new var2;
3021 if (bOverwrite && !bFirstTime)
3022 {
3023 Timer_AddRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, "full", position, date, true);
3024 FormatEx(sQuery, 450, "UPDATE round SET time = '%f', jumps = '%d', fpsmax = '%d', flashbangs = '%d', name = '%s', date = '%s', strafes = '%d', sync = '%f', wr = '%d', vel = '%f', mvel = '%f', avgvel = '%f' WHERE map = '%s' AND auth = '%s' AND physicsdifficulty = '%d' AND part = 'full';", time, jumps, fpsmax, flashbangs, sSafeName, date, strafes, sync, 0, vel, mvel, avgvel, map, sAuthID, physicsDifficulty);
3025 SQL_TQuery(g_hSQL, FinishCallback, sQuery, pack, DBPriority:0);
3026 }
3027 }
3028 new var3;
3029 if (!bOverwrite && !bFirstTime)
3030 {
3031 Call_StartForward(g_hFinishRoundForward);
3032 Call_PushCell(client);
3033 Call_PushString(map);
3034 Call_PushCell(jumps);
3035 Call_PushCell(flashbangs);
3036 Call_PushCell(physicsDifficulty);
3037 Call_PushCell(fpsmax);
3038 Call_PushString(sTimeString);
3039 Call_PushString(sTimeDiff);
3040 Call_PushCell(position);
3041 Call_PushCell(gi_TotalRecords[physicsDifficulty]);
3042 Call_PushCell(bOverwrite);
3043 Call_PushCell(strafes);
3044 Call_PushCell(time);
3045 Call_Finish(0);
3046 }
3047 return 0;
3048}
3049
3050public FinishCallback(Handle:owner, Handle:hndl, String:error[], any:pack)
3051{
3052 if (hndl)
3053 {
3054 new String:map[32];
3055 new String:sTimeString[32];
3056 new String:sTimeDiff[32];
3057 new String:sAuthID[64];
3058 ResetPack(pack, false);
3059 new client = ReadPackCell(pack);
3060 ReadPackString(pack, map, 32);
3061 new jumps = ReadPackCell(pack);
3062 new flashbangs = ReadPackCell(pack);
3063 new physicsDifficulty = ReadPackCell(pack);
3064 new fpsmax = ReadPackCell(pack);
3065 ReadPackString(pack, sTimeString, 32);
3066 ReadPackString(pack, sTimeDiff, 32);
3067 new bOverwrite = ReadPackCell(pack);
3068 new Float:ftime = ReadPackFloat(pack);
3069 new strafes = ReadPackCell(pack);
3070 ReadPackString(pack, sAuthID, 64);
3071 new trikzpartner = ReadPackCell(pack);
3072 new bool:firstTime = ReadPackCell(pack);
3073 new rank = ReadPackCell(pack);
3074 CloseHandle(pack);
3075 new var1;
3076 if (rank == 1 && bOverwrite)
3077 {
3078 if (!g_bTimerPhysics)
3079 {
3080 physicsDifficulty = 1;
3081 }
3082 new var2;
3083 if (g_bTrikz && trikzpartner != -1)
3084 {
3085 SaveGhost_Trikz(client, ftime, jumps, g_timers[trikzpartner][6], physicsDifficulty + -1, trikzpartner, "main");
3086 }
3087 if (g_bTimerGhost)
3088 {
3089 SaveGhost(client, ftime, jumps, physicsDifficulty + -1);
3090 }
3091 }
3092 Call_StartForward(g_hFinishRoundForward);
3093 Call_PushCell(client);
3094 Call_PushString(map);
3095 Call_PushCell(jumps);
3096 Call_PushCell(flashbangs);
3097 Call_PushCell(physicsDifficulty);
3098 Call_PushCell(fpsmax);
3099 Call_PushString(sTimeString);
3100 Call_PushString(sTimeDiff);
3101 Call_PushCell(rank);
3102 Call_PushCell(gi_TotalRecords[physicsDifficulty]);
3103 Call_PushCell(bOverwrite);
3104 Call_PushCell(strafes);
3105 Call_PushCell(firstTime);
3106 Call_PushCell(ftime);
3107 Call_Finish(0);
3108 return 0;
3109 }
3110 Timer_LogError("SQL Error on FinishRound: %s", error);
3111 return 0;
3112}
3113
3114public UpdateRankCallBack(Handle:owner, Handle:hndl, String:error[], any:pack)
3115{
3116 if (hndl)
3117 {
3118 return 0;
3119 }
3120 Timer_LogError("SQL Error on UpdateRank: %s", error);
3121 return 0;
3122}
3123
3124FinishStage(client, String:map[], Float:time, jumps, flashbangs, physicsDifficulty, fpsmax, stagenum, strafes, Float:sync, Float:vel, Float:mvel, Float:avgvel)
3125{
3126 new var1;
3127 if (!IsClientInGame(client) || !IsPlayerAlive(client) || IsFakeClient(client) || g_timers[client][13])
3128 {
3129 return 0;
3130 }
3131 decl String:date[64];
3132 FormatTime(date, 64, NULL_STRING, -1);
3133 new Float:fLastTime = 0.0;
3134 new iLastJumps;
3135 new iLastPlace;
3136 decl String:sTimeDiff[32];
3137 decl String:sBuffer[32];
3138 new bool:bOverwrite;
3139 new bool:bFirstTime;
3140 Timer_GetBestStage(client, physicsDifficulty, fLastTime, iLastJumps, iLastPlace, stagenum);
3141 decl String:StageNum[64];
3142 Format(StageNum, 64, "stage%d", stagenum);
3143 if (!Timer_HasRecord(client, physicsDifficulty, StageNum))
3144 {
3145 bOverwrite = true;
3146 bFirstTime = true;
3147 FormatEx(sTimeDiff, 32, "");
3148 }
3149 else
3150 {
3151 fLastTime -= time;
3152 if (fLastTime < 0.0)
3153 {
3154 fLastTime *= -1.0;
3155 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3156 FormatEx(sTimeDiff, 32, "+%s", sBuffer);
3157 }
3158 if (fLastTime > 0.0)
3159 {
3160 bOverwrite = true;
3161 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3162 FormatEx(sTimeDiff, 32, "-%s", sBuffer);
3163 }
3164 if (0.0 == fLastTime)
3165 {
3166 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3167 FormatEx(sTimeDiff, 32, "%s", sBuffer);
3168 }
3169 }
3170 decl String:sAuthID[64];
3171 GetClientAuthId(client, AuthIdType:1, sAuthID, 64, true);
3172 decl String:sName[32];
3173 GetClientName(client, sName, 32);
3174 decl sSafeName[strlen(sName) * 2 + 1];
3175 SQL_EscapeString(g_hSQL, sName, sSafeName, strlen(sName) * 2 + 1, 0);
3176 decl String:sTimeString[32];
3177 Timer_SecondsToTimeWr(time, sTimeString, 32, true);
3178 decl String:sQuery[452];
3179 new position = Timer_GetTotalRankByTime(time, physicsDifficulty, StageNum);
3180 if (bFirstTime)
3181 {
3182 Timer_AddRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, StageNum, position, date, false);
3183 gi_StageTotalRecords[physicsDifficulty][stagenum]++;
3184 new place;
3185 FormatEx(sQuery, 450, "INSERT INTO round (map, auth, time, jumps, physicsdifficulty, name, fpsmax, flashbangs, part, date, strafes, sync, wr, vel, mvel, avgvel) VALUES ('%s', '%s', %f, %d, %d, '%s', %d, %d, 'stage%d', '%s', '%d', %f, %d, %f, %f, %f);", map, sAuthID, time, jumps, physicsDifficulty, sSafeName, fpsmax, flashbangs, stagenum, date, strafes, sync, place, vel, mvel, avgvel);
3186 SQL_TQuery(g_hSQL, FinishStageCallback, sQuery, any:0, DBPriority:0);
3187 }
3188 else
3189 {
3190 new var2;
3191 if (bOverwrite && !bFirstTime)
3192 {
3193 Timer_AddRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, StageNum, position, date, true);
3194 new place;
3195 FormatEx(sQuery, 450, "UPDATE round SET time = '%f', jumps = '%d', fpsmax = '%d', flashbangs = '%d', name = '%s', date = '%s', strafes = '%d', sync = '%f', wr = '%d', vel = '%f', mvel = '%f', avgvel = '%f' WHERE map = '%s' AND auth = '%s' AND physicsdifficulty = '%d' AND part = 'stage%d';", time, jumps, fpsmax, flashbangs, sSafeName, date, strafes, sync, place, vel, mvel, avgvel, map, sAuthID, physicsDifficulty, stagenum);
3196 SQL_TQuery(g_hSQL, FinishStageCallback, sQuery, any:0, DBPriority:0);
3197 }
3198 }
3199 Call_StartForward(g_hFinishStageForward);
3200 Call_PushCell(client);
3201 Call_PushString(map);
3202 Call_PushCell(jumps);
3203 Call_PushCell(flashbangs);
3204 Call_PushCell(physicsDifficulty);
3205 Call_PushCell(fpsmax);
3206 Call_PushString(sTimeString);
3207 Call_PushString(sTimeDiff);
3208 Call_PushCell(Timer_GetTotalRankByTime(time, physicsDifficulty, StageNum));
3209 Call_PushCell(gi_StageTotalRecords[physicsDifficulty][stagenum]);
3210 Call_PushCell(bOverwrite);
3211 Call_PushCell(stagenum);
3212 Call_PushCell(strafes);
3213 Call_PushCell(bFirstTime);
3214 Call_PushCell(time);
3215 Call_Finish(0);
3216 return 0;
3217}
3218
3219public FinishStageCallback(Handle:owner, Handle:hndl, String:error[], any:pack)
3220{
3221 if (hndl)
3222 {
3223 return 0;
3224 }
3225 Timer_LogError("SQL Error on FinishStage: %s", error);
3226 return 0;
3227}
3228
3229BonusFinishRound(client, String:map[], Float:time, jumps, flashbangs, physicsDifficulty, fpsmax, strafes, Float:sync, Float:vel, Float:mvel, Float:avgvel, bonusNum, trikzpartner)
3230{
3231 new var1;
3232 if (!IsClientInGame(client) || !IsPlayerAlive(client) || IsFakeClient(client) || g_timers[client][13])
3233 {
3234 return 0;
3235 }
3236 decl String:date[64];
3237 FormatTime(date, 64, NULL_STRING, -1);
3238 new Float:fLastTime = 0.0;
3239 new iLastJumps;
3240 new iLastPlace;
3241 decl String:sTimeDiff[32];
3242 decl String:sBuffer[32];
3243 new bool:bOverwrite;
3244 new bool:bFirstTime;
3245 Timer_GetBestBonus(client, physicsDifficulty, fLastTime, iLastJumps, iLastPlace, bonusNum);
3246 decl String:sBonusNum[64];
3247 Format(sBonusNum, 64, "bonus%d", bonusNum);
3248 if (!Timer_HasBonusRecord(client, physicsDifficulty, sBonusNum))
3249 {
3250 bOverwrite = true;
3251 bFirstTime = true;
3252 FormatEx(sTimeDiff, 32, "");
3253 }
3254 else
3255 {
3256 fLastTime -= time;
3257 if (fLastTime < 0.0)
3258 {
3259 fLastTime *= -1.0;
3260 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3261 FormatEx(sTimeDiff, 32, "+%s", sBuffer);
3262 }
3263 if (fLastTime > 0.0)
3264 {
3265 bOverwrite = true;
3266 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3267 FormatEx(sTimeDiff, 32, "-%s", sBuffer);
3268 }
3269 if (0.0 == fLastTime)
3270 {
3271 Timer_SecondsToTimeWr(fLastTime, sBuffer, 32, true);
3272 FormatEx(sTimeDiff, 32, "%s", sBuffer);
3273 }
3274 }
3275 decl String:sAuthID[64];
3276 GetClientAuthId(client, AuthIdType:1, sAuthID, 64, true);
3277 decl String:sName[32];
3278 GetClientName(client, sName, 32);
3279 decl sSafeName[strlen(sName) * 2 + 1];
3280 SQL_EscapeString(g_hSQL, sName, sSafeName, strlen(sName) * 2 + 1, 0);
3281 decl String:sTimeString[32];
3282 Timer_SecondsToTimeWr(time, sTimeString, 32, true);
3283 new position = Timer_GetBonusTotalRankByTime(time, physicsDifficulty, bonusNum);
3284 new Handle:pack = CreateDataPack();
3285 WritePackCell(pack, client);
3286 WritePackString(pack, map);
3287 WritePackCell(pack, jumps);
3288 WritePackCell(pack, flashbangs);
3289 WritePackCell(pack, physicsDifficulty);
3290 WritePackCell(pack, fpsmax);
3291 WritePackString(pack, sTimeString);
3292 WritePackString(pack, sTimeDiff);
3293 WritePackCell(pack, bOverwrite);
3294 WritePackCell(pack, strafes);
3295 WritePackString(pack, sAuthID);
3296 WritePackFloat(pack, time);
3297 WritePackCell(pack, bonusNum);
3298 WritePackCell(pack, trikzpartner);
3299 WritePackCell(pack, bFirstTime);
3300 WritePackCell(pack, position);
3301 decl String:sQuery[452];
3302 if (bFirstTime)
3303 {
3304 Timer_AddBonusRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, sBonusNum, position, date, false);
3305 gi_BonusTotalRecords[physicsDifficulty][bonusNum]++;
3306 new place;
3307 FormatEx(sQuery, 450, "INSERT INTO bround (map, auth, time, jumps, physicsdifficulty, name, fpsmax, flashbangs, part, date, strafes, sync, wr, vel, mvel, avgvel) VALUES ('%s', '%s', %f, %d, %d, '%s', %d, %d, '%s', '%s', %d, %f, %d, %f, %f, %f);", map, sAuthID, time, jumps, physicsDifficulty, sSafeName, fpsmax, flashbangs, sBonusNum, date, strafes, sync, place, vel, mvel, avgvel);
3308 SQL_TQuery(g_hSQL, FinishBonusCallback, sQuery, pack, DBPriority:0);
3309 }
3310 else
3311 {
3312 new var2;
3313 if (bOverwrite && !bFirstTime)
3314 {
3315 Timer_AddBonusRecord(client, time, jumps, flashbangs, physicsDifficulty, strafes, sync, vel, mvel, avgvel, sBonusNum, position, date, true);
3316 new place;
3317 FormatEx(sQuery, 450, "UPDATE bround SET time = '%f', jumps = '%d', fpsmax = '%d', flashbangs = '%d', name = '%s', date = '%s', strafes = '%d', sync = '%f', wr = '%d', vel = '%f', mvel = '%f', avgvel = '%f' WHERE map = '%s' AND auth = '%s' AND physicsdifficulty = '%d' AND part = '%s';", time, jumps, fpsmax, flashbangs, sSafeName, date, strafes, sync, place, vel, mvel, avgvel, map, sAuthID, physicsDifficulty, sBonusNum);
3318 SQL_TQuery(g_hSQL, FinishBonusCallback, sQuery, pack, DBPriority:0);
3319 }
3320 }
3321 new var3;
3322 if (!bOverwrite && !bFirstTime)
3323 {
3324 Call_StartForward(g_hFinishBonusRoundForward);
3325 Call_PushCell(client);
3326 Call_PushString(map);
3327 Call_PushCell(jumps);
3328 Call_PushCell(flashbangs);
3329 Call_PushCell(physicsDifficulty);
3330 Call_PushCell(fpsmax);
3331 Call_PushString(sTimeString);
3332 Call_PushString(sTimeDiff);
3333 Call_PushCell(position);
3334 Call_PushCell(gi_BonusTotalRecords[physicsDifficulty][bonusNum]);
3335 Call_PushCell(bOverwrite);
3336 Call_PushCell(strafes);
3337 Call_PushCell(bonusNum);
3338 Call_PushCell(time);
3339 Call_Finish(0);
3340 }
3341 return 0;
3342}
3343
3344public FinishBonusCallback(Handle:owner, Handle:hndl, String:error[], any:pack)
3345{
3346 if (hndl)
3347 {
3348 new String:map[32];
3349 new String:sTimeString[32];
3350 new String:sTimeDiff[32];
3351 new String:sAuthID[64];
3352 ResetPack(pack, false);
3353 new client = ReadPackCell(pack);
3354 ReadPackString(pack, map, 32);
3355 new jumps = ReadPackCell(pack);
3356 new flashbangs = ReadPackCell(pack);
3357 new physicsDifficulty = ReadPackCell(pack);
3358 new fpsmax = ReadPackCell(pack);
3359 ReadPackString(pack, sTimeString, 32);
3360 ReadPackString(pack, sTimeDiff, 32);
3361 new bOverwrite = ReadPackCell(pack);
3362 new strafes = ReadPackCell(pack);
3363 ReadPackString(pack, sAuthID, 64);
3364 new Float:fTime = ReadPackFloat(pack);
3365 new bonusNum = ReadPackCell(pack);
3366 new trikzpartner = ReadPackCell(pack);
3367 new bool:firstTime = ReadPackCell(pack);
3368 new rank = ReadPackCell(pack);
3369 CloseHandle(pack);
3370 decl String:sBonusNum[64];
3371 Format(sBonusNum, 64, "bonus%d", bonusNum);
3372 new var1;
3373 if (rank == 1 && bOverwrite && bonusNum == 1)
3374 {
3375 if (!g_bTimerPhysics)
3376 {
3377 physicsDifficulty = 1;
3378 }
3379 new var2;
3380 if (g_bTrikz && trikzpartner != -1)
3381 {
3382 SaveGhost_Trikz(client, fTime, jumps, g_timers[trikzpartner][6], physicsDifficulty + -1, trikzpartner, "bonus");
3383 }
3384 if (g_bTimerGhost)
3385 {
3386 SaveGhostBonus(client, fTime, jumps, physicsDifficulty + -1);
3387 }
3388 }
3389 Call_StartForward(g_hFinishBonusRoundForward);
3390 Call_PushCell(client);
3391 Call_PushString(map);
3392 Call_PushCell(jumps);
3393 Call_PushCell(flashbangs);
3394 Call_PushCell(physicsDifficulty);
3395 Call_PushCell(fpsmax);
3396 Call_PushString(sTimeString);
3397 Call_PushString(sTimeDiff);
3398 Call_PushCell(rank);
3399 Call_PushCell(gi_BonusTotalRecords[physicsDifficulty][bonusNum]);
3400 Call_PushCell(bOverwrite);
3401 Call_PushCell(strafes);
3402 Call_PushCell(bonusNum);
3403 Call_PushCell(firstTime);
3404 Call_PushCell(fTime);
3405 Call_Finish(0);
3406 return 0;
3407 }
3408 Timer_LogError("SQL Error on FinishRound: %s", error);
3409 return 0;
3410}
3411
3412Float:CalculateTime(client)
3413{
3414 new var1;
3415 if (g_timers[client][0] && g_timers[client][13])
3416 {
3417 return g_timers[client][14] - g_timers[client][3] - g_timers[client][18];
3418 }
3419 new var2;
3420 if (g_timers[client][0])
3421 {
3422 var2 = GetEngineTime();
3423 }
3424 else
3425 {
3426 var2 = g_timers[client][5];
3427 }
3428 return var2 - g_timers[client][3] - g_timers[client][18];
3429}
3430
3431ConnectSQL()
3432{
3433 if (g_hSQL)
3434 {
3435 CloseHandle(g_hSQL);
3436 }
3437 g_hSQL = MissingTAG:0;
3438 if (SQL_CheckConfig("timer"))
3439 {
3440 SQL_TConnect(ConnectSQLCallback, "timer", any:0);
3441 }
3442 else
3443 {
3444 SetFailState("PLUGIN STOPPED - Reason: no config entry found for 'timer' in databases.cfg - PLUGIN STOPPED");
3445 }
3446 return 0;
3447}
3448
3449public ConnectSQLCallback(Handle:owner, Handle:hndl, String:error[], any:data)
3450{
3451 if (g_iReconnectCounter >= 5)
3452 {
3453 Timer_LogError("PLUGIN STOPPED - Reason: reconnect counter reached max - PLUGIN STOPPED");
3454 return 0;
3455 }
3456 if (hndl)
3457 {
3458 decl String:sDriver[16];
3459 SQL_GetDriverIdent(owner, sDriver, 16);
3460 g_hSQL = CloneHandle(hndl, Handle:0);
3461 if (StrEqual(sDriver, "mysql", false))
3462 {
3463 SQL_TQuery(g_hSQL, SetNamesCallback, "SET NAMES 'utf8'", any:0, DBPriority:0);
3464 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `round` (`id` int(11) NOT NULL AUTO_INCREMENT, `map` varchar(32) NOT NULL, `auth` varchar(32) NOT NULL, `time` float NOT NULL, `jumps` int(11) NOT NULL, `physicsdifficulty` int(11) NOT NULL, `name` varchar(64) NOT NULL, `fpsmax` int(11) NOT NULL, `flashbangs` int(11) NOT NULL, `part` varchar(32) NOT NULL, `date` varchar(32) NOT NULL, `strafes` int(11) NOT NULL, `sync` float NOT NULL, `wr` int(11) NOT NULL, `vel` float NOT NULL, `mvel` float NOT NULL, `avgvel` float NOT NULL, PRIMARY KEY (`id`));", any:0, DBPriority:1);
3465 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `bround` (`id` int(11) NOT NULL AUTO_INCREMENT, `map` varchar(32) NOT NULL, `auth` varchar(32) NOT NULL, `time` float NOT NULL, `jumps` int(11) NOT NULL, `physicsdifficulty` int(11) NOT NULL, `name` varchar(64) NOT NULL, `fpsmax` int(11) NOT NULL, `flashbangs` int(11) NOT NULL, `part` varchar(32) NOT NULL, `date` varchar(32) NOT NULL, `strafes` int(11) NOT NULL, `sync` float NOT NULL, `wr` int(11) NOT NULL, `vel` float NOT NULL, `mvel` float NOT NULL, `avgvel` float NOT NULL, PRIMARY KEY (`id`));", any:0, DBPriority:1);
3466 }
3467 else
3468 {
3469 if (StrEqual(sDriver, "sqlite", false))
3470 {
3471 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `round` (`id` INTEGER PRIMARY KEY, `map` varchar(32) NOT NULL, `auth` varchar(32) NOT NULL, `time` float NOT NULL, `jumps` INTEGER NOT NULL, `physicsdifficulty` INTEGER NOT NULL, `name` varchar(64) NOT NULL, `fpsmax` INTEGER NOT NULL, `flashbangs` INTEGER NOT NULL, `part` varchar(32) NOT NULL, `date` varchar(32) NOT NULL, `strafes` INTEGER NOT NULL, `sync` float NOT NULL, `wr` INTEGER NOT NULL, `vel` float NOT NULL, `mvel` float NOT NULL, `avgvel` float NOT NULL);", any:0, DBPriority:1);
3472 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "CREATE TABLE IF NOT EXISTS `bround` (`id` INTEGER PRIMARY KEY, `map` varchar(32) NOT NULL, `auth` varchar(32) NOT NULL, `time` float NOT NULL, `jumps` INTEGER NOT NULL, `physicsdifficulty` INTEGER NOT NULL, `name` varchar(64) NOT NULL, `fpsmax` INTEGER NOT NULL, `flashbangs` INTEGER NOT NULL, `part` varchar(32) NOT NULL, `date` varchar(32) NOT NULL, `strafes` INTEGER NOT NULL, `sync` float NOT NULL, `wr` INTEGER NOT NULL, `vel` float NOT NULL, `mvel` float NOT NULL, `avgvel` float NOT NULL);", any:0, DBPriority:1);
3473 }
3474 }
3475 SQL_TQuery(g_hSQL, CheckFlashbangsCallback, "SELECT flashbangs FROM round", any:0, DBPriority:1);
3476 SQL_TQuery(g_hSQL, CheckFlashbangsCallback, "SELECT flashbangs FROM bround", any:0, DBPriority:1);
3477 g_iReconnectCounter = 1;
3478 return 0;
3479 }
3480 Timer_LogError("Connection to SQL database has failed, Reason: %s", error);
3481 g_iReconnectCounter += 1;
3482 ConnectSQL();
3483 return 0;
3484}
3485
3486public SetNamesCallback(Handle:owner, Handle:hndl, String:error[], any:data)
3487{
3488 if (hndl)
3489 {
3490 return 0;
3491 }
3492 Timer_LogError("SQL Error on SetNames: %s", error);
3493 return 0;
3494}
3495
3496public CreateSQLTableCallback(Handle:owner, Handle:hndl, String:error[], any:data)
3497{
3498 if (owner)
3499 {
3500 if (hndl)
3501 {
3502 return 0;
3503 }
3504 Timer_LogError("SQL Error on CreateSQLTable: %s", error);
3505 return 0;
3506 }
3507 Timer_LogError(error);
3508 g_iReconnectCounter += 1;
3509 ConnectSQL();
3510 return 0;
3511}
3512
3513public CheckFlashbangsCallback(Handle:owner, Handle:hndl, String:error[], any:data)
3514{
3515 if (!hndl)
3516 {
3517 decl String:sDriver[16];
3518 SQL_ReadDriver(g_hSQL, sDriver, 16);
3519 if (StrEqual(sDriver, "mysql", false))
3520 {
3521 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "ALTER TABLE `round` ADD `flashbangs` int(11) NOT NULL;", any:0, DBPriority:1);
3522 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "ALTER TABLE `bround` ADD `flashbangs` int(11) NOT NULL;", any:0, DBPriority:1);
3523 }
3524 else
3525 {
3526 if (StrEqual(sDriver, "sqlite", false))
3527 {
3528 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "ALTER TABLE `round` ADD `flashbangs` INTEGER NOT NULL;", any:0, DBPriority:1);
3529 SQL_TQuery(g_hSQL, CreateSQLTableCallback, "ALTER TABLE `bround` ADD `flashbangs` INTEGER NOT NULL;", any:0, DBPriority:1);
3530 }
3531 }
3532 }
3533 return 0;
3534}
3535
3536public OnFinishRound(client, String:map[], jumps, flashbangs, physicsDifficulty, fpsmax, String:timeString[], String:timeDiffString[], position, totalrank, bool:overwrite, strafes, bool:firstRecord, Float:fTime)
3537{
3538 new String:sMessage[512];
3539 new String:sName[32];
3540 GetClientName(client, sName, 32);
3541 FormatEx(sMessage, 512, "%t%t", "Prefix", "Round Finish Message", sName, timeString, timeDiffString);
3542 if (g_bShowJumps)
3543 {
3544 Format(sMessage, 512, "%s %t", sMessage, "Jumps Message", jumps);
3545 }
3546 if (g_bShowStrafes)
3547 {
3548 Format(sMessage, 512, "%s %t", sMessage, "Strafes Message", strafes);
3549 }
3550 if (g_bShowFlashbangs)
3551 {
3552 Format(sMessage, 512, "%s %t", sMessage, "Flashbangs Message", flashbangs);
3553 }
3554 new String:sDifficulty[32];
3555 if (g_bTimerPhysics)
3556 {
3557 Timer_GetDifficultyName(physicsDifficulty, sDifficulty, 32);
3558 Format(sMessage, 512, "%s %t", sMessage, "Difficulty Message", sDifficulty);
3559 }
3560 Format(sMessage, 512, "%s. %t", sMessage, "Rank Message", position, totalrank);
3561 StringToUpper(sDifficulty);
3562 new var1;
3563 if (position == 1 && overwrite)
3564 {
3565 CPrintToChatAll("{red}-- WORLD RECORD --");
3566 CPrintToChatAll("{pink}-- WORLD RECORD --");
3567 CPrintToChatAll("{lightblue}-- WORLD RECORD --");
3568 CPrintToChatAll("{green}NEW {pink}%s {green}WORLD RECORD", sDifficulty);
3569 }
3570 else
3571 {
3572 new var2;
3573 if (position == 2 && overwrite)
3574 {
3575 CPrintToChatAll("%t", "{lightblue}Second Record Message", sDifficulty);
3576 }
3577 new var3;
3578 if (position == 3 && overwrite)
3579 {
3580 CPrintToChatAll("%t", "{lightblue}Third Record Message", sDifficulty);
3581 }
3582 }
3583 if (overwrite)
3584 {
3585 CPrintToChatAll(sMessage);
3586 }
3587 else
3588 {
3589 CPrintToChat(client, sMessage);
3590 }
3591 return 0;
3592}
3593
3594public OnFinishStage(client, String:map[], jumps, flashbangs, physicsDifficulty, fpsmax, String:timeString[], String:timeDiffString[], position, totalrank, bool:overwrite, stagenum, strafes, bool:firstTime)
3595{
3596 decl String:sMessage[512];
3597 decl String:sName[32];
3598 GetClientName(client, sName, 32);
3599 FormatEx(sMessage, 512, "%t%t", "Prefix", "Stage Finish Message", stagenum, timeString, timeDiffString);
3600 if (g_bShowJumps)
3601 {
3602 Format(sMessage, 512, "%s %t", sMessage, "Jumps Message", jumps);
3603 }
3604 if (g_bShowStrafes)
3605 {
3606 Format(sMessage, 512, "%s %t", sMessage, "Strafes Message", strafes);
3607 }
3608 if (g_bShowFlashbangs)
3609 {
3610 Format(sMessage, 512, "%s %t", sMessage, "Flashbangs Message", flashbangs);
3611 }
3612 if (g_bTimerPhysics)
3613 {
3614 new String:sDifficulty[32];
3615 Timer_GetDifficultyName(physicsDifficulty, sDifficulty, 32);
3616 Format(sMessage, 512, "%s %t", sMessage, "Difficulty Message", sDifficulty);
3617 }
3618 if (Timer_GetStageCount() == stagenum)
3619 {
3620 g_timers[client][1] = 0;
3621 }
3622 if (Timer_GetStageCount() > 1)
3623 {
3624 CPrintToChat(client, sMessage);
3625 }
3626 return 0;
3627}
3628
3629public OnBonusFinishRound(client, String:map[], jumps, flashbangs, physicsDifficulty, fpsmax, String:timeString[], String:timeDiffString[], position, totalrank, bool:overwrite, strafes, bonusNum)
3630{
3631 decl String:sMessage[512];
3632 decl String:sName[32];
3633 GetClientName(client, sName, 32);
3634 FormatEx(sMessage, 512, "%t%t", "BonusPrefix", "Bonus Finish Message", sName, timeString, timeDiffString, bonusNum);
3635 if (g_bShowJumps)
3636 {
3637 Format(sMessage, 512, "%s %t", sMessage, "Jumps Message", jumps);
3638 }
3639 if (g_bShowStrafes)
3640 {
3641 Format(sMessage, 512, "%s %t", sMessage, "Strafes Message", strafes);
3642 }
3643 if (g_bShowFlashbangs)
3644 {
3645 Format(sMessage, 512, "%s %t", sMessage, "Flashbangs Message", flashbangs);
3646 }
3647 new String:sDifficulty[32];
3648 if (g_bTimerPhysics)
3649 {
3650 Timer_GetDifficultyName(physicsDifficulty, sDifficulty, 32);
3651 Format(sMessage, 512, "%s %t", sMessage, "Difficulty Message", sDifficulty);
3652 }
3653 Format(sMessage, 512, "%s. %t", sMessage, "Rank Message", position, totalrank);
3654 StringToUpper(sDifficulty);
3655 new var1;
3656 if (position == 1 && overwrite)
3657 {
3658 CPrintToChatAll("%t", "Bonus First Record Message", sDifficulty, bonusNum);
3659 }
3660 else
3661 {
3662 new var2;
3663 if (position == 2 && overwrite)
3664 {
3665 CPrintToChatAll("%t", "Bonus Second Record Message", sDifficulty, bonusNum);
3666 }
3667 new var3;
3668 if (position == 3 && overwrite)
3669 {
3670 CPrintToChatAll("%t", "Bonus Third Record Message", sDifficulty, bonusNum);
3671 }
3672 }
3673 if (overwrite)
3674 {
3675 CPrintToChatAll(sMessage);
3676 }
3677 else
3678 {
3679 CPrintToChat(client, sMessage);
3680 }
3681 return 0;
3682}
3683
3684public Native_TimerStart(Handle:plugin, numParams)
3685{
3686 return StartTimer(GetNativeCell(1));
3687}
3688
3689public Native_StageStart(Handle:plugin, numParams)
3690{
3691 new bool:practice = GetNativeCell(2);
3692 return StartStage(GetNativeCell(1), practice, GetNativeCell(3));
3693}
3694
3695public Native_TimerStop(Handle:plugin, numParams)
3696{
3697 return StopTimer(GetNativeCell(1), GetNativeCell(2));
3698}
3699
3700public Native_TimerRestart(Handle:plugin, numParams)
3701{
3702 return RestartTimer(GetNativeCell(1));
3703}
3704
3705public Native_BonusTimerRestart(Handle:plugin, numParams)
3706{
3707 return BonusRestartTimer(GetNativeCell(1), GetNativeCell(2));
3708}
3709
3710public Native_TimerPause(Handle:plugin, numParams)
3711{
3712 return PauseTimer(GetNativeCell(1));
3713}
3714
3715public Native_TimerResume(Handle:plugin, numParams)
3716{
3717 return ResumeTimer(GetNativeCell(1));
3718}
3719
3720public Native_GetClientTimer(Handle:plugin, numParams)
3721{
3722 new client = GetNativeCell(1);
3723 SetNativeCellRef(2, g_timers[client][0]);
3724 SetNativeCellRef(3, CalculateTime(client));
3725 SetNativeCellRef(4, g_timers[client][6]);
3726 SetNativeCellRef(5, g_timers[client][20]);
3727 SetNativeCellRef(6, g_timers[client][8]);
3728 SetNativeCellRef(7, g_timers[client][11]);
3729 if (g_timers[client][23] > 0)
3730 {
3731 SetNativeCellRef(8, float(g_timers[client][21]) / g_timers[client][23] * 100.0);
3732 }
3733 else
3734 {
3735 SetNativeCellRef(8, any:0);
3736 }
3737 return 1;
3738}
3739
3740public Native_GetClientTimerADV(Handle:plugin, numParams)
3741{
3742 new client = GetNativeCell(1);
3743 SetNativeCellRef(2, g_timers[client][0]);
3744 SetNativeCellRef(3, CalculateTime(client));
3745 SetNativeCellRef(4, g_timers[client][6]);
3746 SetNativeCellRef(5, g_timers[client][20]);
3747 SetNativeCellRef(6, g_timers[client][8]);
3748 SetNativeCellRef(7, g_timers[client][11]);
3749 if (g_timers[client][23] > 0)
3750 {
3751 SetNativeCellRef(8, float(g_timers[client][21]) / g_timers[client][23] * 100.0);
3752 }
3753 else
3754 {
3755 SetNativeCellRef(8, any:0);
3756 }
3757 SetNativeCellRef(9, g_timers[client][33]);
3758 SetNativeCellRef(10, g_timers[client][29]);
3759 SetNativeCellRef(11, g_timers[client][31] / g_timers[client][34]);
3760 return 1;
3761}
3762
3763public Native_GetClientStageTimerADV(Handle:plugin, numParams)
3764{
3765 new client = GetNativeCell(1);
3766 SetNativeCellRef(2, g_timers[client][1]);
3767 SetNativeCellRef(3, GetEngineTime() - g_timers[client][4] - g_timers[client][19]);
3768 SetNativeCellRef(4, g_timers[client][7]);
3769 SetNativeCellRef(5, g_timers[client][9]);
3770 SetNativeCellRef(6, g_timers[client][10]);
3771 SetNativeCellRef(7, g_timers[client][12]);
3772 if (0 < g_timers[client][24])
3773 {
3774 SetNativeCellRef(8, float(g_timers[client][22]) / g_timers[client][24] * 100.0);
3775 }
3776 else
3777 {
3778 SetNativeCellRef(8, any:0);
3779 }
3780 SetNativeCellRef(9, g_timers[client][33]);
3781 SetNativeCellRef(10, g_timers[client][30]);
3782 SetNativeCellRef(11, g_timers[client][32] / g_timers[client][35]);
3783 return 1;
3784}
3785
3786public Native_GetClientStageTimer(Handle:plugin, numParams)
3787{
3788 new client = GetNativeCell(1);
3789 SetNativeCellRef(2, g_timers[client][1]);
3790 SetNativeCellRef(3, GetEngineTime() - g_timers[client][4] - g_timers[client][19]);
3791 SetNativeCellRef(4, g_timers[client][7]);
3792 SetNativeCellRef(5, g_timers[client][9]);
3793 SetNativeCellRef(6, g_timers[client][10]);
3794 SetNativeCellRef(7, g_timers[client][12]);
3795 if (0 < g_timers[client][24])
3796 {
3797 SetNativeCellRef(8, float(g_timers[client][22]) / g_timers[client][24] * 100.0);
3798 }
3799 else
3800 {
3801 SetNativeCellRef(8, any:0);
3802 }
3803 SetNativeCellRef(9, g_timers[client][2]);
3804 return 1;
3805}
3806
3807public Native_SetClientTimer(Handle:plugin, numParams)
3808{
3809 new client = GetNativeCell(1);
3810 g_timers[client][0] = 1;
3811 g_timers[client][3] = GetNativeCellRef(2);
3812 g_timers[client][5] = 0;
3813 g_timers[client][6] = GetNativeCellRef(3);
3814 g_timers[client][8] = 0;
3815 g_timers[client][13] = 0;
3816 g_timers[client][14] = 0;
3817 g_timers[client][18] = 0;
3818 return 1;
3819}
3820
3821public Native_FinishRound(Handle:plugin, numParams)
3822{
3823 new client = GetNativeCell(1);
3824 decl String:map[32];
3825 GetNativeString(2, map, 32, 0);
3826 new Float:time = GetNativeCell(3);
3827 new jumps = GetNativeCell(4);
3828 new flashbangs = GetNativeCell(5);
3829 new physicsDifficulty = GetNativeCell(6);
3830 new fpsmax = GetNativeCell(7);
3831 new strafes = GetNativeCell(8);
3832 new Float:sync = GetNativeCell(9);
3833 new Float:vel = GetNativeCell(10);
3834 new Float:mvel = GetNativeCell(11);
3835 new Float:avgvel = GetNativeCell(12);
3836 new trikzpartner = GetNativeCell(13);
3837 FinishRound(client, map, time, jumps, flashbangs, physicsDifficulty, fpsmax, strafes, sync, vel, mvel, avgvel, trikzpartner);
3838 return 0;
3839}
3840
3841public Native_BonusFinishRound(Handle:plugin, numParams)
3842{
3843 new client = GetNativeCell(1);
3844 decl String:map[32];
3845 GetNativeString(2, map, 32, 0);
3846 new Float:time = GetNativeCell(3);
3847 new jumps = GetNativeCell(4);
3848 new flashbangs = GetNativeCell(5);
3849 new physicsDifficulty = GetNativeCell(6);
3850 new fpsmax = GetNativeCell(7);
3851 new strafes = GetNativeCell(8);
3852 new Float:sync = GetNativeCell(9);
3853 new Float:vel = GetNativeCell(10);
3854 new Float:mvel = GetNativeCell(11);
3855 new Float:avgvel = GetNativeCell(12);
3856 new bonusNum = GetNativeCell(13);
3857 new trikzpartner = GetNativeCell(14);
3858 BonusFinishRound(client, map, time, jumps, flashbangs, physicsDifficulty, fpsmax, strafes, sync, vel, mvel, avgvel, bonusNum, trikzpartner);
3859 return 0;
3860}
3861
3862public Native_FinishStage(Handle:plugin, numParams)
3863{
3864 new client = GetNativeCell(1);
3865 decl String:map[32];
3866 GetNativeString(2, map, 32, 0);
3867 new Float:time = GetNativeCell(3);
3868 new jumps = GetNativeCell(4);
3869 new flashbangs = GetNativeCell(5);
3870 new physicsDifficulty = GetNativeCell(6);
3871 new fpsmax = GetNativeCell(7);
3872 new stagenum = GetNativeCell(8);
3873 new strafes = GetNativeCell(9);
3874 new Float:sync = GetNativeCell(10);
3875 new Float:vel = GetNativeCell(11);
3876 new Float:mvel = GetNativeCell(12);
3877 new Float:avgvel = GetNativeCell(13);
3878 FinishStage(client, map, time, jumps, flashbangs, physicsDifficulty, fpsmax, stagenum, strafes, sync, vel, mvel, avgvel);
3879 return 0;
3880}
3881
3882public Native_IsPaused(Handle:plugin, numParams)
3883{
3884 new client = GetNativeCell(1);
3885 return g_timers[client][13];
3886}