1 | #include <cctype> |
2 | #include <list> |
3 | |
4 | #include <game/client/gameclient.h> |
5 | #include <game/mapitems.h> |
6 | |
7 | #include "race.h" |
8 | |
9 | int CRaceHelper::ms_aFlagIndex[2] = {-1, -1}; |
10 | |
11 | int CRaceHelper::TimeFromSecondsStr(const char *pStr) |
12 | { |
13 | while(*pStr == ' ') // skip leading spaces |
14 | pStr++; |
15 | if(!isdigit(*pStr)) |
16 | return -1; |
17 | int Time = str_toint(str: pStr) * 1000; |
18 | while(isdigit(*pStr)) |
19 | pStr++; |
20 | if(*pStr == '.' || *pStr == ',') |
21 | { |
22 | pStr++; |
23 | static const int s_aMult[3] = {100, 10, 1}; |
24 | for(size_t i = 0; i < std::size(s_aMult) && isdigit(pStr[i]); i++) |
25 | Time += (pStr[i] - '0') * s_aMult[i]; |
26 | } |
27 | return Time; |
28 | } |
29 | |
30 | int CRaceHelper::TimeFromStr(const char *pStr) |
31 | { |
32 | static const char *const s_pMinutesStr = " minute(s) " ; |
33 | static const char *const s_pSecondsStr = " second(s)" ; |
34 | |
35 | const char *pSeconds = str_find(haystack: pStr, needle: s_pSecondsStr); |
36 | if(!pSeconds) |
37 | return -1; |
38 | |
39 | const char *pMinutes = str_find(haystack: pStr, needle: s_pMinutesStr); |
40 | if(pMinutes) |
41 | { |
42 | while(*pStr == ' ') // skip leading spaces |
43 | pStr++; |
44 | int SecondsTime = TimeFromSecondsStr(pStr: pMinutes + str_length(str: s_pMinutesStr)); |
45 | if(SecondsTime == -1 || !isdigit(*pStr)) |
46 | return -1; |
47 | return str_toint(str: pStr) * 60 * 1000 + SecondsTime; |
48 | } |
49 | else |
50 | return TimeFromSecondsStr(pStr); |
51 | } |
52 | |
53 | int CRaceHelper::TimeFromFinishMessage(const char *pStr, char *pNameBuf, int NameBufSize) |
54 | { |
55 | static const char *const s_pFinishedStr = " finished in: " ; |
56 | const char *pFinished = str_find(haystack: pStr, needle: s_pFinishedStr); |
57 | if(!pFinished) |
58 | return -1; |
59 | |
60 | int FinishedPos = pFinished - pStr; |
61 | if(FinishedPos == 0 || FinishedPos >= NameBufSize) |
62 | return -1; |
63 | |
64 | str_copy(dst: pNameBuf, src: pStr, dst_size: FinishedPos + 1); |
65 | |
66 | return TimeFromStr(pStr: pFinished + str_length(str: s_pFinishedStr)); |
67 | } |
68 | |
69 | bool CRaceHelper::IsStart(CGameClient *pClient, vec2 Prev, vec2 Pos) |
70 | { |
71 | CCollision *pCollision = pClient->Collision(); |
72 | if(pClient->m_GameInfo.m_FlagStartsRace) |
73 | { |
74 | int EnemyTeam = pClient->m_aClients[pClient->m_Snap.m_LocalClientId].m_Team ^ 1; |
75 | return ms_aFlagIndex[EnemyTeam] != -1 && distance(a: Pos, b: pCollision->GetPos(Index: ms_aFlagIndex[EnemyTeam])) < 32; |
76 | } |
77 | else |
78 | { |
79 | std::vector<int> vIndices = pCollision->GetMapIndices(PrevPos: Prev, Pos); |
80 | if(!vIndices.empty()) |
81 | for(int &Indice : vIndices) |
82 | { |
83 | if(pCollision->GetTileIndex(Index: Indice) == TILE_START) |
84 | return true; |
85 | if(pCollision->GetFTileIndex(Index: Indice) == TILE_START) |
86 | return true; |
87 | } |
88 | else |
89 | { |
90 | if(pCollision->GetTileIndex(Index: pCollision->GetPureMapIndex(Pos)) == TILE_START) |
91 | return true; |
92 | if(pCollision->GetFTileIndex(Index: pCollision->GetPureMapIndex(Pos)) == TILE_START) |
93 | return true; |
94 | } |
95 | } |
96 | return false; |
97 | } |
98 | |