diff --git a/.gitignore b/.gitignore index cba1fc094..502ac5d80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ +bam .bam config.lua datasrc/__pycache__ datasrc/*.pyc objs src/game/generated +SDL.dll +autoexec.cfg crapnet* dilate* diff --git a/data/languages/bosnian.txt b/data/languages/bosnian.txt index 78d12e9eb..7ecf0afd0 100644 --- a/data/languages/bosnian.txt +++ b/data/languages/bosnian.txt @@ -894,6 +894,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/czech.txt b/data/languages/czech.txt index 5abeb0879..3b03b0b48 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -891,6 +891,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/dutch.txt b/data/languages/dutch.txt index cadc9eb54..32fcc6c7a 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -963,6 +963,9 @@ no limit Name plates size == +Unable to delete the demo +== + ##### old translations ##### ##### DDRace ##### diff --git a/data/languages/finnish.txt b/data/languages/finnish.txt index 33ff92aa5..c11d1f1cf 100644 --- a/data/languages/finnish.txt +++ b/data/languages/finnish.txt @@ -894,6 +894,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/french.txt b/data/languages/french.txt index 051eeb61e..804a57e82 100644 --- a/data/languages/french.txt +++ b/data/languages/french.txt @@ -286,9 +286,6 @@ Grenade Group == Groupe -HD -== HD - Hammer == Maillet @@ -924,6 +921,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Use Clipping == diff --git a/data/languages/german.txt b/data/languages/german.txt index bfb6c1571..f8deb9411 100644 --- a/data/languages/german.txt +++ b/data/languages/german.txt @@ -963,6 +963,9 @@ no limit Name plates size == +Unable to delete the demo +== + ##### old translations ##### ##### DDRace ##### diff --git a/data/languages/index.txt b/data/languages/index.txt index a65bafc3b..b30297c2c 100644 --- a/data/languages/index.txt +++ b/data/languages/index.txt @@ -28,6 +28,9 @@ polish portuguese == Português +romanian +== Română + russian == Русский diff --git a/data/languages/italian.txt b/data/languages/italian.txt index 569fd228a..0e75f2d3a 100644 --- a/data/languages/italian.txt +++ b/data/languages/italian.txt @@ -888,6 +888,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/polish.txt b/data/languages/polish.txt index 1380a1e1e..5a08fbee7 100644 --- a/data/languages/polish.txt +++ b/data/languages/polish.txt @@ -939,6 +939,9 @@ Tiles Time limit: %d min == +Unable to delete the demo +== + Up == diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index 5ec214b93..028c29f51 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -894,6 +894,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/romanian.txt b/data/languages/romanian.txt new file mode 100644 index 000000000..9e33ca351 --- /dev/null +++ b/data/languages/romanian.txt @@ -0,0 +1,970 @@ + +##### translated strings ##### + +%d of %d servers, %d players +== %d/%d servere, %d jucători + +%d%% loaded +== %d%% încărcat + +%ds left +== %ds a ieșit + +%i minute left +== %i minute rămas + +%i minutes left +== %i minutes rămase + +%i second left +== %i secundă rămasă + +%i seconds left +== %i secunde rămase + +%s Right click for context menu. +== %s Clic dreapta pentru meniul contextual. + +Abort +== Anulează + +Add +== Adaugă + +Add Image +== Adaugă o imagine + +Add Quad +== Adaugă quad + +Add group +== Adaugă un grup + +Add quads layer +== Adaugă strat quad-uri + +Add tile layer +== Adaugă strat cu plăci + +Address +== Adresa + +Adds a new group +== Adaugă un grup nou + +Adds a new quad +== Adaugă un nou quad + +All +== Toți + +Alpha +== Alfa + +Alpha value of the envelope +== Valoarea alfa a plicului + +Always show name plates +== Afișează întotdeauna pseudonimele + +Anim +== Anim. + +Append +== Adaugă + +Append map +== Adaugă unei hărți + +Are you sure that you want to delete the demo? +== Sigur vrei să ștergi demo-ul? + +Are you sure that you want to quit? +== Sigur vrei să ieși? + +As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server. +== Aceasta fiind prima lansare a jocului, te rog introdu-ți pseudonimul mai jos. E recomandat să verifici setările și să le ajustezi cum vrei înainte să intri pe un server. + +Aspect ratio +== Rația de aspect + +Automatically record demos +== Înregistrează automat demo-uri + +Automatically take game over screenshot +== Fă automat o captură de ecran la final + +Blue team +== Echipa albastră + +Blue team wins! +== Echipa albastră a câștigat! + +Blue value of the envelope +== Valoarea albastră a plicului + +Body +== Corp + +Border +== Bordură + +CCW +== ST + +CW +== DR + +Call vote +== Votează + +Cancel +== Anulează + +Chat +== Chat + +Clear collision +== Curăță coliziunea + +Clip H +== Î clip + +Clip W +== L clip + +Clip X +== X clip + +Clip Y +== Y clip + +Close +== Închide + +Color +== Culoare + +Color Env +== Culoare Env + +Color TO +== Culoare TO + +Color+ +== Culoare+ + +Compatible version +== Versiune compatibilă + +Connect +== Conectează + +Connecting to +== Conectare la + +Connection Problems... +== Probleme la conexiune... + +Console +== Consolă + +Constructs collision from this layer +== Construiește coliziunea din acest strat + +Controls +== Controale + +Creates a new color envelope +== Creează un plic într-o culoare nouă + +Creates a new map +== Creează o hartă nouă + +Creates a new pos envelope +== Creează un nou plic poz + +Creates a new quad layer +== Creează un nou strat quad + +Creates a new tile layer +== Creează un nou strat de plăci + +Current +== Curent + +Current version: %s +== Versiunea actuală : %s + +Custom colors +== Culori personalizate + +Decrease +== Redu + +Decrease animation speed +== Redu viteza animațiilor + +Delete +== Șterge + +Delete demo +== Șterge demonstrația + +Delete group +== Șterge grupul + +Delete layer +== Șterge stratul + +Delete this envelope +== Șterge acest plic + +Deletes the current quad +== Șterge acest quad + +Deletes the layer +== Șterge stratul + +Demos +== Demo + +Detail +== Detalii + +Disconnect +== Deconectare + +Disconnected +== Deconectat + +Display Modes +== Moduri de afișare + +Down +== Jos + +Downloading map +== Se descarcă harta + +Draw! +== Egalitate! + +Dynamic Camera +== Cameră dinamică + +Embed +== Integrează + +Embedded +== Integrat + +Embeds the image into the map file. +== Integrează imaginea în fișierul hărții. + +Emoticon +== Figurine + +Enable/disable group for saving +== Comută salvarea grupului + +Enable/disable layer for saving +== Comută salvarea stratului + +Enter +== Intră + +Envelopes +== Plicuri + +Error +== Eroare + +Error loading demo +== Eroare la încărcarea demo-ului + +Exit +== Ieșire + +Exits from the editor +== Închide editorul + +External +== Extern + +FSAA samples +== Eșantioane FSAA + +Favorite +== Favorit + +Favorites +== Favorite + +Feet +== Picioare + +File +== Fișier + +File: %s +== Fișier : %s + +Filename: +== Numele fișierului: + +Filter +== Filtre + +Fire +== Foc + +Folder +== Dosar + +Force vote +== Forțează votul + +Fullscreen +== Ecrat complet + +Game +== Joc + +Game info +== Informații joc + +Game over +== Final de joc + +Game type +== Tip de joc + +Game types: +== Tipuri de joc: + +General +== General + +Graphics +== Grafică + +Green value of the envelope +== Valoarea verde a plicului + +Grenade +== Grenade + +Group +== Grup + +HD +== HD + +Hammer +== Ciocan + +Has people playing +== Are jucători activi + +Height +== Înălțime + +High Detail +== Detalii înalte + +Hook +== Cârlig + +Host address +== Adresa gazdei + +Hue +== Tentă + +Image +== Imagine + +Images +== Imagini + +Increase +== Mărește + +Increase animation speed +== Mărește viteza animației + +Info +== Informații + +Internet +== Internet + +Invalid Demo +== Demo nevalid + +Join blue +== La albaștri + +Join game +== Intră în joc + +Join red +== La roșii + +Jump +== Salt + +Kick +== Dă afară + +LAN +== LAN + +Language +== Limba + +Layers +== Straturi + +Left +== Stânga + +Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate. +== Clic stânga pentru mutare. Ține Shift pentru mutare pibot. Ține Ctrl pentru rotire. + +Left mouse button to move. Hold shift to move the texture. +== Clic stânga pentru mutare. Ține Shift pentru mutarea texturii. + +Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point aswell. Right click to delete. +== Clic stânga pentru tragere. Ține Ctrl pentru precizie. Ține Shift pentru modificarea timpului. Clic dreapta pentru ștergere. + +Lht. +== Lum. + +Load +== Încarcă + +Load a new image to use in the map +== Încarcă o imagine pentru utilizarea pe hartă + +Load map +== Încarcă o hartă + +Loading +== Se încarcă + +MOTD +== Mesajul zilei + +Make collision +== Creează coliziunea + +Make external +== Fă-o externă + +Map +== Hartă + +Max Screenshots +== Număr maxim de capturi de ecran + +Max demos +== Număr maxim de demo-uri + +Maximum ping: +== Ping maxim: + +Miscellaneous +== Diverse + +Mouse sens. +== Sensib. maus + +Move left +== Mută la stânga + +Move right +== Mută la dreapta + +Movement +== Mișcare + +Mute when not active +== Mută la inactivate + +Name +== Nume + +Name plates size +== Dimensiune nume placă + +Name: +== Nume: + +New +== Nou + +New folder +== Dosar nou + +News +== Știri + +Next Envelope +== Plicul următor + +Next weapon +== Arma următoare + +Nickname +== Pseudonim + +No +== Nu + +No password +== Fără parolă + +No servers found +== Nici un server găsit + +No servers match your filter criteria +== Nici un server nu corespunde criteriilor + +None +== Niciunul + +Normal animation speed +== Viteza normală a animațiilor + +Ok +== Bine + +Open +== Deschide + +Opens a map and adds everything from that map to the current one +== Deschide o hartă și adaugă totul de pe ea pe cea curentă + +Opens a map for editing +== Deschide o hartă pentru editare + +Order +== Ordine + +Para X +== Para X + +Para Y +== Para Y + +Parent Folder +== Dosarul părinte + +Password +== Parolă + +Password incorrect +== Parolă incorectă + +Ping +== Ping + +Pistol +== Pistol + +Play +== Joacă + +Player +== Jucător + +Players +== Jucători + +Please balance teams! +== Echilibrați echipele! + +Pos X +== Poz X + +Pos Y +== Poz Y + +Pos. Env +== Poz Env + +Pos. TO +== Poz TO + +Pos.+ +== Pos.+ + +Press right mouse button to create a new point +== Clic-dreapta pentru crearea unui punct nou + +Prev. weapon +== Arma precedentă + +Previous Envelope +== Plicul anterior + +Proof +== Negativ + +Quads +== Quad-uri + +Quality Textures +== Texturi de înaltă calitate + +Quick search: +== Căutare rapidă: + +Quit +== Ieșire + +REC +== REC + +Reason: +== Motiv: + +Record demo +== Înreg. demo + +Red team +== Echipa roșie + +Red team wins! +== Echipa roșie a câștigat! + +Red value of the envelope +== Valoarea roșie a plicului + +Refocus +== Refocus + +Refresh +== Reîncarcă + +Refreshing master servers +== Reîncarcă serverele principale + +Remote console +== Consolă server + +Remove +== Elimină + +Removes collision from this layer +== Elimină coliziunea din acest strat + +Removes the image from the map +== Elimină imaginea din hartă + +Removes the image from the map file. +== Elimină imaginea din fișierul hărții. + +Replace +== Înlocuiește + +Replace Image +== Înlocuiește imaginea + +Replaces the image with a new one +== Înlocuiește imaginea cu una nouă + +Reset filter +== Filtru implicit + +Reset to defaults +== Setări implicite + +Resizes the current Quad based on the aspect ratio of the image +== Redimensionează quad-ul curent în baza rației de aspect a imaginii + +Rifle +== Mitralieră + +Right +== Dreapta + +Rotation of the brush in degrees. Use left mouse button to drag and change the value. Hold shift to be more precise. +== Rotația pensulei în grade. Folosește butonul stânga al mausului pentru a trage și modifica valoarea. Ține Shift pentru precizie. + +Rotation of the envelope +== Rotirea plicului + +Round +== Runda + +Sample rate +== Frecvența + +Sat. +== Sat. + +Save +== Salvează + +Save As +== Salvează ca + +Save map +== Salvează harta + +Saves the current map +== Salvează harta curentă + +Saves the current map under a new name +== Salvează harta curentă sub un nume nou + +Score +== Scor + +Score board +== Scoruri + +Score limit +== Limita de scor + +Scoreboard +== Scoruri + +Screenshot +== Captură de ecran + +Select group. Right click for properties. +== Alege un grup. Clic-dreapta pentru proprietăți. + +Select image +== Alege o imagine + +Select layer. Right click for properties. +== Alege un strat. Clic-dreapta pentru prorpietăți. + +Server details +== Detalii server + +Server info +== Info. server + +Server not full +== Are locuri libere + +Settings +== Setări + +Shift +== Shift + +Shotgun +== Pușcă + +Show chat +== Afișare chat + +Show name plates +== Arată pseudonimele + +Show only supported +== Arată doar modurile suportate + +Skins +== Costume + +Sound +== Sunet + +Sound volume +== Volum sunet + +Spectate +== Spectator + +Spectators +== Spectatori + +Square +== Pătrat + +Squares the current quad +== Fă pătrat quad-ul curent + +Standard gametype +== Jocuri standard + +Standard map +== Hărți standard + +Stop record +== Stop înreg. + +Sudden Death +== Moarte subită + +Switch between images and layers managment. +== Comută între gestiune imagini și straturi. + +Switch curve type +== Comută tipul de curbă + +Switch weapon on pickup +== Schimbă arma la găsire + +Team +== Echipa + +Team chat +== Chat cu echipa + +Teeworlds %s is out! Download it at www.teeworlds.com! +== Teeworlds %s este lansat! Descarcă-l de la www.teeworlds.com! + +Texture Compression +== Compresie texturi + +The server is running a non-standard tuning on a pure game type. +== Serverul folosește parametri ne-standard într-un joc standard. + +Tiles +== Plăci + +Time limit +== Timp limită + +Time limit: %d min +== Timp limită : %d min + +Toggle group visibility +== Comută vizibilitatea grupului + +Toggle layer visibility +== Comută vizibilitatea stratului + +Toggles the envelope editor. +== Comută editorul de plicuri. + +Try again +== Reîncearcă + +Type +== Tip + +UI Color +== Culoare meniu + +Up +== Sus + +Use Clipping +== Folosește decuparea + +Use left mouse button to drag and change the color value. Hold shift to be more precise. +== Folosește butonul stâng al mausului pentru a trage și schimba valoarea culorii. Ține Shift pentru precizie. + +Use left mouse button to drag and change the value. Hold shift to be more precise. +== Folosește butonul stâng al mausului pentru a trage și schimba valoarea. Ține Shift pentru precizie. + +Use left mouse button to drag and create a brush. +== Folosește butonul stâng al mausului pentru a trage și crea o pensulă. + +Use left mouse button to paint with the brush. Right button clears the brush. +== Folosește butonul stâng al mausului pentru a picta cu pensula. Clic dreapta curăță pensula. + +Use sounds +== Folosește sunetul + +V-Sync +== Sincronizare verticală (V-Sync) + +Version +== Versiune + +Vote no +== Votează nu + +Vote yes +== Votează da + +Voting +== Votare + +Warmup +== Încălzire + +Weapon +== Arme + +Welcome to Teeworlds +== Bun venit în Teeworlds + +Width +== Lățime + +X-axis of the envelope +== Axa-X a plicului + +Y-axis of the envelope +== Axa-Y a plicului + +Yes +== Da + +You must restart the game for all settings to take effect. +== Trebuie să repornești jocul pentru aplicarea setărilor. + +Your skin +== Costumul tău + +ZI +== MA + +ZO +== MI + +[HOME] Restore map focus +== [HOME] Restaurează focusul hărții + +[M] Flip brush vertical +== [M] Întoarce pe verticală + +[N] Flip brush horizontal +== [N] Întoarce pe orizontală + +[NumPad*] Zoom to normal and remove editor offset +== [NumPad*] Focalizare normală și eliminare deplasament editor + +[NumPad+] Zoom in +== [Numeric+] Mărire + +[NumPad-] Zoom out +== [Numeric-] Micșorare + +[R] Rotates the brush counter clockwise +== [R] Rotește peria spre stânga + +[T] Rotates the brush clockwise +== [T] Rotește peria spre dreapta + +[ctrl+h] Toggle High Detail +== [Ctrl+H] Comută detaliile înalte + +[ctrl+m] Toggle animation +== [Ctrl+M] Comută animația + +[ctrl+p] Toggles proof borders. These borders represent what a player maximum can see. +== [Ctrl+P] Comută bordurile negativului. Aceste borduri reprezintă maximul vizibil jucătorilor. + +no limit +== fără limită + +##### needs translation ##### + +Unable to delete the demo +== + +##### old translations ##### + diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 53165a806..2facf9d11 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -939,6 +939,9 @@ Tiles Time limit: %d min == +Unable to delete the demo +== + Up == diff --git a/data/languages/serbian.txt b/data/languages/serbian.txt index 63b8f87a3..ad1c0346a 100644 --- a/data/languages/serbian.txt +++ b/data/languages/serbian.txt @@ -894,6 +894,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/swedish.txt b/data/languages/swedish.txt index 330444a96..1a3112945 100644 --- a/data/languages/swedish.txt +++ b/data/languages/swedish.txt @@ -888,6 +888,9 @@ Toggle layer visibility Toggles the envelope editor. == +Unable to delete the demo +== + Up == diff --git a/data/languages/ukrainian.txt b/data/languages/ukrainian.txt index bc9b1de87..dbaffce0e 100644 --- a/data/languages/ukrainian.txt +++ b/data/languages/ukrainian.txt @@ -945,6 +945,9 @@ Rotation of the envelope Shift == +Unable to delete the demo +== + Up == diff --git a/scripts/update_localization.py b/scripts/update_localization.py index 6baa6d47e..61fb6c5b9 100644 --- a/scripts/update_localization.py +++ b/scripts/update_localization.py @@ -8,8 +8,8 @@ source_exts = [".c", ".cpp", ".h"] def parse_source(): stringtable = {} def process_line(line): - if 'Localize("' in line: - fields = line.split('Localize("', 1)[1].split('"', 1) + if b'Localize("' in line: + fields = line.split(b'Localize("', 1)[1].split(b'"', 1) stringtable[fields[0]] = "" process_line(fields[1]) @@ -23,21 +23,21 @@ def parse_source(): if filename[-2:] in source_exts or filename[-4:] in source_exts: for line in open(filename, "rb"): process_line(line) - + return stringtable def load_languagefile(filename): f = open(filename, "rb") lines = f.readlines() f.close() - + stringtable = {} for i in range(0, len(lines)-1): - l = lines[i].decode("utf-8").strip() - if len(l) and not l[0] == '=' and not l[0] == '#': - stringtable[l] = lines[i+1][3:].decode("utf-8").rstrip() - + l = lines[i].strip() + if len(l) and not l[0:1] == b"=" and not l[0:1] == b"#": + stringtable[l] = lines[i+1][3:].rstrip() + return stringtable def generate_languagefile(outputfilename, srctable, loctable): @@ -52,28 +52,27 @@ def generate_languagefile(outputfilename, srctable, loctable): srctable_keys.append(key) srctable_keys.sort() - content = "\n##### translated strings #####\n\n" + content = b"\n##### translated strings #####\n\n" for k in srctable_keys: if k in loctable and len(loctable[k]): - content += "%s\n== %s\n\n" % (k, loctable[k]) + content += k + b"\n== " + loctable[k] + b"\n\n" num_items += 1 - - content += "##### needs translation #####\n\n" + content += b"##### needs translation #####\n\n" for k in srctable_keys: if not k in loctable or len(loctable[k]) == 0: - content += "%s\n== \n\n" % (k) + content += k + b"\n== \n\n" num_items += 1 new_items += 1 - content += "##### old translations #####\n\n" + content += b"##### old translations #####\n\n" for k in loctable: if not k in srctable: - content += "%s\n== %s\n\n" % (k, loctable[k]) + content += k + b"\n== " + loctable[k] + b"\n\n" num_items += 1 old_items += 1 - - f.write(content.encode("utf-8")) + + f.write(content) f.close() print("%-40s %8d %8d %8d" % (outputfilename, num_items, new_items, old_items)) @@ -86,6 +85,6 @@ for filename in os.listdir("../data/languages"): continue if filename == "index.txt": continue - + filename = "../data/languages/" + filename generate_languagefile(filename, srctable, load_languagefile(filename)) diff --git a/src/engine/client.h b/src/engine/client.h index ab1f05479..80a0241d8 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -77,6 +77,7 @@ public: virtual void Quit() = 0; virtual const char *DemoPlayer_Play(const char *pFilename, int StorageType) = 0; virtual void DemoRecorder_Start(const char *pFilename, bool WithTimestamp) = 0; + virtual void DemoRecorder_HandleAutoStart() = 0; virtual void DemoRecorder_Stop() = 0; virtual void AutoScreenshot_Start() = 0; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 948feca20..6cfc77be9 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2159,6 +2159,7 @@ void CClient::DemoRecorder_HandleAutoStart() { if(g_Config.m_ClAutoDemoRecord) { + DemoRecorder_Stop(); DemoRecorder_Start("auto/autorecord", true); if(g_Config.m_ClAutoDemoMax) { diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index 828aa3fd6..d24c41aef 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -688,21 +688,20 @@ public: if(pChr) { + Advance = pChr->m_AdvanceX + Kerning(pFont, Character, Nextcharacter)*Scale; + if(pCursor->m_Flags&TEXTFLAG_STOP_AT_END && DrawX+Advance*Size-pCursor->m_StartX > pCursor->m_LineWidth) + { + // we hit the end of the line, no more to render or count + pCurrent = pEnd; + break; + } + if(pCursor->m_Flags&TEXTFLAG_RENDER) { Graphics()->QuadsSetSubset(pChr->m_aUvs[0], pChr->m_aUvs[1], pChr->m_aUvs[2], pChr->m_aUvs[3]); IGraphics::CQuadItem QuadItem(DrawX+pChr->m_OffsetX*Size, DrawY+pChr->m_OffsetY*Size, pChr->m_Width*Size, pChr->m_Height*Size); Graphics()->QuadsDrawTL(&QuadItem, 1); } - - Advance = pChr->m_AdvanceX + Kerning(pFont, Character, Nextcharacter)*Scale; - } - - if(pCursor->m_Flags&TEXTFLAG_STOP_AT_END && DrawX+(Advance+pChr->m_Width)*Size-pCursor->m_StartX > pCursor->m_LineWidth) - { - // we hit the end of the line, no more to render or count - pCurrent = pEnd; - break; } DrawX += Advance*Size; diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 0269c4b4d..b618b92e0 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -264,7 +264,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client { while(pStr && *pStr) { - CResult *pResult = new(&m_ExecutionQueue.m_pLast->m_Result) CResult; + CResult Result; const char *pEnd = pStr; const char *pNextPart = 0; int InString = 0; @@ -292,24 +292,24 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client pEnd++; } - if(ParseStart(pResult, pStr, (pEnd-pStr) + 1) != 0) + if(ParseStart(&Result, pStr, (pEnd-pStr) + 1) != 0) return; - CCommand *pCommand = FindCommand(pResult->m_pCommand, m_FlagMask); + CCommand *pCommand = FindCommand(Result.m_pCommand, m_FlagMask); if(pCommand) { int IsStrokeCommand = 0; - if(pResult->m_pCommand[0] == '+') + if(Result.m_pCommand[0] == '+') { // insert the stroke direction token - pResult->AddArgument(m_paStrokeStr[Stroke]); + Result.AddArgument(m_paStrokeStr[Stroke]); IsStrokeCommand = 1; } if(Stroke || IsStrokeCommand) { - if(ParseArgs(pResult, pCommand->m_pParams)) + if(ParseArgs(&Result, pCommand->m_pParams)) { RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); char aBuf[256]; @@ -319,14 +319,15 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client } else if(m_StoreCommands && pCommand->m_Flags&CFGFLAG_STORE) { + m_ExecutionQueue.AddEntry(); m_ExecutionQueue.m_pLast->m_pfnCommandCallback = pCommand->m_pfnCallback; m_ExecutionQueue.m_pLast->m_pCommandUserData = pCommand->m_pUserData; - m_ExecutionQueue.AddEntry(); + m_ExecutionQueue.m_pLast->m_Result = Result; } else { - if(pResult->GetVictim() == CResult::VICTIM_ME) - pResult->SetVictim(ClientId); + if(Result.GetVictim() == CResult::VICTIM_ME) + Result.SetVictim(ClientId); if((ClientLevel < pCommand->m_Level && !(pCommand->m_Flags & CMDFLAG_HELPERCMD)) || (ClientLevel < 1 && (pCommand->m_Flags & CMDFLAG_HELPERCMD))) { @@ -346,7 +347,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client ReleaseAlternativePrintResponseCallback(); } - else if(ClientLevel == 1 && (pCommand->m_Flags & CMDFLAG_HELPERCMD) && pResult->GetVictim() != ClientId) + else if(ClientLevel == 1 && (pCommand->m_Flags & CMDFLAG_HELPERCMD) && Result.GetVictim() != ClientId) { RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); PrintResponse(OUTPUT_LEVEL_STANDARD, "Console", "As a helper you can't use commands on others."); @@ -369,19 +370,19 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client } else { - if (pResult->HasVictim()) + if (Result.HasVictim()) { - if(pResult->GetVictim() == CResult::VICTIM_ALL) + if(Result.GetVictim() == CResult::VICTIM_ALL) { for (int i = 0; i < MAX_CLIENTS; i++) { if (ClientOnline(i) && CompareClients(ClientLevel, i)) { - pResult->SetVictim(i); + Result.SetVictim(i); RegisterAlternativePrintCallback(pfnAlternativePrintCallback, pUserData); RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); - pCommand->m_pfnCallback(pResult, pCommand->m_pUserData, ClientId); + pCommand->m_pfnCallback(&Result, pCommand->m_pUserData, ClientId); ReleaseAlternativePrintResponseCallback(); ReleaseAlternativePrintCallback(); @@ -390,13 +391,13 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client } else { - if (!ClientOnline(pResult->GetVictim())) + if (!ClientOnline(Result.GetVictim())) { RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); PrintResponse(OUTPUT_LEVEL_STANDARD, "Console", "client is offline"); ReleaseAlternativePrintResponseCallback(); } - else if (!CompareClients(ClientLevel, pResult->GetVictim()) && ClientId != pResult->GetVictim()) + else if (!CompareClients(ClientLevel, Result.GetVictim()) && ClientId != Result.GetVictim()) { RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); PrintResponse(OUTPUT_LEVEL_STANDARD, "Console", "you can not use commands on players with the same or higher level than you"); @@ -407,7 +408,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client RegisterAlternativePrintCallback(pfnAlternativePrintCallback, pUserData); RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); - pCommand->m_pfnCallback(pResult, pCommand->m_pUserData, ClientId); + pCommand->m_pfnCallback(&Result, pCommand->m_pUserData, ClientId); ReleaseAlternativePrintResponseCallback(); ReleaseAlternativePrintCallback(); @@ -419,7 +420,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client RegisterAlternativePrintCallback(pfnAlternativePrintCallback, pUserData); RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); - pCommand->m_pfnCallback(pResult, pCommand->m_pUserData, ClientId); + pCommand->m_pfnCallback(&Result, pCommand->m_pUserData, ClientId); ReleaseAlternativePrintResponseCallback(); ReleaseAlternativePrintCallback(); @@ -433,7 +434,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr, const int Client RegisterAlternativePrintResponseCallback(pfnAlternativePrintResponseCallback, pResponseUserData); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "No such command: %s.", pResult->m_pCommand); + str_format(aBuf, sizeof(aBuf), "No such command: %s.", Result.m_pCommand); PrintResponse(OUTPUT_LEVEL_STANDARD, "Console", aBuf); ReleaseAlternativePrintResponseCallback(); @@ -762,7 +763,7 @@ void CConsole::StoreCommands(bool Store, int ClientId) { if(!Store) { - for(CExecutionQueue::CQueueEntry *pEntry = m_ExecutionQueue.m_pFirst; pEntry != m_ExecutionQueue.m_pLast; pEntry = pEntry->m_pNext) + for(CExecutionQueue::CQueueEntry *pEntry = m_ExecutionQueue.m_pFirst; pEntry; pEntry = pEntry->m_pNext) pEntry->m_pfnCommandCallback(&pEntry->m_Result, pEntry->m_pCommandUserData, ClientId); m_ExecutionQueue.Reset(); } diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 8807b8fe6..f0815c224 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -6,6 +6,9 @@ #include #include "memheap.h" + +#include + class CConsole : public IConsole { class CCommand : public CCommandInfo @@ -81,6 +84,29 @@ class CConsole : public IConsole const char *m_pCommand; const char *m_apArgs[MAX_PARTS]; + + CResult() : IResult() + { + mem_zero(m_aStringStorage, sizeof(m_aStringStorage)); + m_pArgsStart = 0; + m_pCommand = 0; + mem_zero(m_apArgs, sizeof(m_apArgs)); + } + + CResult &operator =(const CResult &Other) + { + if(this != &Other) + { + IResult::operator=(Other); + int Offset = m_aStringStorage - Other.m_aStringStorage; + mem_copy(m_aStringStorage, Other.m_aStringStorage, sizeof(m_aStringStorage)); + m_pArgsStart = Other.m_pArgsStart + Offset; + m_pCommand = Other.m_pCommand + Offset; + for(unsigned i = 0; i < Other.m_NumArgs; ++i) + m_apArgs[i] = Other.m_apArgs[i] + Offset; + } + return *this; + } enum { @@ -127,14 +153,17 @@ class CConsole : public IConsole { CQueueEntry *pEntry = static_cast(m_Queue.Allocate(sizeof(CQueueEntry))); pEntry->m_pNext = 0; - m_pLast->m_pNext = pEntry; + if(!m_pFirst) + m_pFirst = pEntry; + if(m_pLast) + m_pLast->m_pNext = pEntry; m_pLast = pEntry; + (void)new(&(pEntry->m_Result)) CResult; } void Reset() { m_Queue.Reset(); - m_pFirst = m_pLast = static_cast(m_Queue.Allocate(sizeof(CQueueEntry))); - m_pLast->m_pNext = 0; + m_pFirst = m_pLast = 0; } } m_ExecutionQueue; diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index a4940ed76..37876562c 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -8,6 +8,8 @@ #include +#include + #include "broadcast.h" void CBroadcast::OnReset() @@ -17,13 +19,16 @@ void CBroadcast::OnReset() void CBroadcast::OnRender() { + if(m_pClient->m_pScoreboard->Active()) + return; + Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300); if(time_get() < m_BroadcastTime) { CTextCursor Cursor; TextRender()->SetCursor(&Cursor, m_BroadcastRenderOffset, 40.0f, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-2*m_BroadcastRenderOffset; + Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-m_BroadcastRenderOffset; TextRender()->TextEx(&Cursor, m_aBroadcastText, -1); } } diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 9c75bccee..f54a45d70 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -62,7 +62,14 @@ void CHud::RenderGameTimer() str_format(Buf, sizeof(Buf), "%02d:%02d.%d", Time/60, Time%60, m_DDRaceTick/10); float FontSize = 10.0f; float w = TextRender()->TextWidth(0, 12,"00:00.0",-1); + // last 60 sec red, last 10 sec blink + if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit && Time <= 60) + { + float Alpha = Time <= 10 && (2*time_get()/time_freq()) % 2 ? 0.5f : 1.0f; + TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha); + } TextRender()->Text(0, Half-w/2, 2, FontSize, Buf, -1); + TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); } } @@ -79,66 +86,133 @@ void CHud::RenderSuddenDeath() } void CHud::RenderScoreHud() -{ - int GameFlags = m_pClient->m_Snap.m_pGameobj->m_Flags; - float Whole = 300*Graphics()->ScreenAspect(); - +{ // render small score hud - if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) && (GameFlags&GAMEFLAG_TEAMS)) + if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) { - char aScoreTeam[2][32]; - str_format(aScoreTeam[TEAM_RED], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); - str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue); - float aScoreTeamWidth[2] = {TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_RED], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_BLUE], -1)}; - float ScoreWidthMax = max(max(aScoreTeamWidth[TEAM_RED], aScoreTeamWidth[TEAM_BLUE]), TextRender()->TextWidth(0, 14.0f, "100", -1)); - float Split = 3.0f; - float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split; - - for(int t = 0; t < 2; t++) + int GameFlags = m_pClient->m_Snap.m_pGameobj->m_Flags; + float Whole = 300*Graphics()->ScreenAspect(); + + if(GameFlags&GAMEFLAG_TEAMS) { - // draw box - Graphics()->BlendNormal(); - Graphics()->TextureSet(-1); - Graphics()->QuadsBegin(); - if(t == 0) - Graphics()->SetColor(1.0f, 0.0f, 0.0f, 0.25f); - else - Graphics()->SetColor(0.0f, 0.0f, 1.0f, 0.25f); - RenderTools()->DrawRoundRectExt(Whole-ScoreWidthMax-ImageSize-2*Split, 245.0f+t*20, ScoreWidthMax+ImageSize+2*Split, 18.0f, 5.0f, CUI::CORNER_L); - Graphics()->QuadsEnd(); - - // draw score - TextRender()->Text(0, Whole-ScoreWidthMax+(ScoreWidthMax-aScoreTeamWidth[t])/2-Split, 245.0f+t*20, 14.0f, aScoreTeam[t], -1); - - if(GameFlags&GAMEFLAG_FLAGS && m_pClient->m_Snap.m_paFlags[t]) + char aScoreTeam[2][32]; + str_format(aScoreTeam[TEAM_RED], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); + str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue); + float aScoreTeamWidth[2] = {TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_RED], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_BLUE], -1)}; + float ScoreWidthMax = max(max(aScoreTeamWidth[TEAM_RED], aScoreTeamWidth[TEAM_BLUE]), TextRender()->TextWidth(0, 14.0f, "100", -1)); + float Split = 3.0f; + float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split; + + for(int t = 0; t < 2; t++) { - if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -2 || (m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -1 && ((Client()->GameTick()/10)&1))) - { - // draw flag - Graphics()->BlendNormal(); - Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); - Graphics()->QuadsBegin(); - RenderTools()->SelectSprite(t==0?SPRITE_FLAG_RED:SPRITE_FLAG_BLUE); - IGraphics::CQuadItem QuadItem(Whole-ScoreWidthMax-ImageSize, 246.0f+t*20, ImageSize/2, ImageSize); - Graphics()->QuadsDrawTL(&QuadItem, 1); - Graphics()->QuadsEnd(); - } - else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0) - { - // draw name of the flag holder - int Id = m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy%MAX_CLIENTS; - const char *pName = m_pClient->m_aClients[Id].m_aName; - float w = TextRender()->TextWidth(0, 10.0f, pName, -1); - TextRender()->Text(0, Whole-ScoreWidthMax-ImageSize-3*Split-w, 247.0f+t*20, 10.0f, pName, -1); + // draw box + Graphics()->BlendNormal(); + Graphics()->TextureSet(-1); + Graphics()->QuadsBegin(); + if(t == 0) + Graphics()->SetColor(1.0f, 0.0f, 0.0f, 0.25f); + else + Graphics()->SetColor(0.0f, 0.0f, 1.0f, 0.25f); + RenderTools()->DrawRoundRectExt(Whole-ScoreWidthMax-ImageSize-2*Split, 245.0f+t*20, ScoreWidthMax+ImageSize+2*Split, 18.0f, 5.0f, CUI::CORNER_L); + Graphics()->QuadsEnd(); - // draw tee of the flag holder - CTeeRenderInfo Info = m_pClient->m_aClients[Id].m_RenderInfo; - Info.m_Size = 18.0f; - RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), - vec2(Whole-ScoreWidthMax-Info.m_Size/2-Split, 246.0f+Info.m_Size/2+t*20)); + // draw score + TextRender()->Text(0, Whole-ScoreWidthMax+(ScoreWidthMax-aScoreTeamWidth[t])/2-Split, 245.0f+t*20, 14.0f, aScoreTeam[t], -1); + + if(GameFlags&GAMEFLAG_FLAGS && m_pClient->m_Snap.m_paFlags[t]) + { + if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -2 || (m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -1 && ((Client()->GameTick()/10)&1))) + { + // draw flag + Graphics()->BlendNormal(); + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); + Graphics()->QuadsBegin(); + RenderTools()->SelectSprite(t==0?SPRITE_FLAG_RED:SPRITE_FLAG_BLUE); + IGraphics::CQuadItem QuadItem(Whole-ScoreWidthMax-ImageSize, 246.0f+t*20, ImageSize/2, ImageSize); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->QuadsEnd(); + } + else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0) + { + // draw name of the flag holder + int Id = m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy%MAX_CLIENTS; + const char *pName = m_pClient->m_aClients[Id].m_aName; + float w = TextRender()->TextWidth(0, 10.0f, pName, -1); + TextRender()->Text(0, Whole-ScoreWidthMax-ImageSize-3*Split-w, 247.0f+t*20, 10.0f, pName, -1); + + // draw tee of the flag holder + CTeeRenderInfo Info = m_pClient->m_aClients[Id].m_RenderInfo; + Info.m_Size = 18.0f; + RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), + vec2(Whole-ScoreWidthMax-Info.m_Size/2-Split, 246.0f+Info.m_Size/2+t*20)); + } } } } + else + { + int Local = 1; + int aPos[2] = { 1, 2 }; + const CNetObj_PlayerInfo *apPlayerInfo[2] = { m_pClient->m_Snap.m_paInfoByScore[0], 0 }; + if(m_pClient->m_Snap.m_paInfoByScore[0]) + { + if(m_pClient->m_Snap.m_paInfoByScore[0]->m_ClientId == m_pClient->m_Snap.m_LocalCid) + { + apPlayerInfo[1] = m_pClient->m_Snap.m_paInfoByScore[1]; + Local = 0; + } + else + for(int i = 1; i < MAX_CLIENTS; ++i) + if(m_pClient->m_Snap.m_paInfoByScore[i]->m_ClientId == m_pClient->m_Snap.m_LocalCid) + { + apPlayerInfo[1] = m_pClient->m_Snap.m_paInfoByScore[i]; + aPos[1] = i+1; + break; + } + } + char aScore[2][32]; + for(int t = 0; t < 2; ++t) + { + if(apPlayerInfo[t]) + str_format(aScore[t], sizeof(aScore)/2, "%d", apPlayerInfo[t]->m_Score); + else + aScore[t][0] = 0; + } + float aScoreWidth[2] = {TextRender()->TextWidth(0, 14.0f, aScore[0], -1), TextRender()->TextWidth(0, 14.0f, aScore[1], -1)}; + float ScoreWidthMax = max(max(aScoreWidth[0], aScoreWidth[1]), TextRender()->TextWidth(0, 14.0f, "10", -1)); + float Split = 3.0f, ImageSize = 16.0f, PosSize = 16.0f; + + for(int t = 0; t < 2; t++) + { + // draw box + Graphics()->BlendNormal(); + Graphics()->TextureSet(-1); + Graphics()->QuadsBegin(); + if(t == Local) + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); + else + Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.25f); + RenderTools()->DrawRoundRectExt(Whole-ScoreWidthMax-ImageSize-2*Split-PosSize, 245.0f+t*20, ScoreWidthMax+ImageSize+2*Split+PosSize, 18.0f, 5.0f, CUI::CORNER_L); + Graphics()->QuadsEnd(); + + // draw score + TextRender()->Text(0, Whole-ScoreWidthMax+(ScoreWidthMax-aScoreWidth[t])/2-Split, 245.0f+t*20, 14.0f, aScore[t], -1); + + // draw tee + if(apPlayerInfo[t]) + { + CTeeRenderInfo Info = m_pClient->m_aClients[apPlayerInfo[t]->m_ClientId].m_RenderInfo; + Info.m_Size = 18.0f; + RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, EMOTE_NORMAL, vec2(1,0), + vec2(Whole-ScoreWidthMax-Info.m_Size/2-Split, 246.0f+Info.m_Size/2+t*20)); + } + + // draw position + char aBuf[32]; + str_format(aBuf, sizeof(aBuf), "%d.", aPos[t]); + TextRender()->Text(0, Whole-ScoreWidthMax-ImageSize-Split-PosSize, 247.0f+t*20, 10.0f, aBuf, -1); + } + } } } diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 76a072d9e..af42dae6c 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1111,6 +1111,10 @@ void CMenus::SetActive(bool Active) m_pClient->OnRelease(); } } + else if(Client()->State() == IClient::STATE_DEMOPLAYBACK) + { + m_pClient->OnRelease(); + } } void CMenus::OnReset() diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 7f330bd07..5e49b3eee 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -498,6 +498,7 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) ServerDetails.HSplitBottom(10.0f, &ServerDetails, 0x0); // server details + CTextCursor Cursor; const float FontSize = 12.0f; ServerDetails.HSplitTop(20.0f, &ServerHeader, &ServerDetails); RenderTools()->DrawUIRect(&ServerHeader, vec4(1,1,1,0.25f), CUI::CORNER_T, 4.0f); @@ -545,15 +546,21 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) } RightColumn.HSplitTop(15.0f, &Row, &RightColumn); - UI()->DoLabelScaled(&Row, pSelectedServer->m_aVersion, FontSize, -1); + TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Row.w; + TextRender()->TextEx(&Cursor, pSelectedServer->m_aVersion, -1); RightColumn.HSplitTop(15.0f, &Row, &RightColumn); - UI()->DoLabelScaled(&Row, pSelectedServer->m_aGameType, FontSize, -1); + TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Row.w; + TextRender()->TextEx(&Cursor, pSelectedServer->m_aGameType, -1); char aTemp[16]; str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_Latency); RightColumn.HSplitTop(15.0f, &Row, &RightColumn); - UI()->DoLabelScaled(&Row, aTemp, FontSize, -1); + TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Row.w; + TextRender()->TextEx(&Cursor, aTemp, -1); } @@ -579,11 +586,12 @@ void CMenus::RenderServerbrowserServerDetail(CUIRect View) ServerScoreBoard.HSplitTop(16.0f, &Row, &ServerScoreBoard); str_format(aTemp, sizeof(aTemp), "%d", pSelectedServer->m_aPlayers[i].m_Score); - UI()->DoLabelScaled(&Row, aTemp, FontSize, -1); + TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = 25.0f; + TextRender()->TextEx(&Cursor, aTemp, -1); Row.VSplitLeft(25.0f, 0x0, &Row); - - CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Row.x, Row.y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Row.w; diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 8d0a54691..e6ff92c60 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -130,8 +130,9 @@ void CMenus::RenderDemoPlayer(CUIRect MainView) if(CurrentTick == TotalTicks) { - DemoPlayer()->Pause(); - DemoPlayer()->SetPos(0); + m_pClient->OnReset(); + DemoPlayer()->Pause(); + DemoPlayer()->SetPos(0); } if(m_MenuActive) @@ -160,6 +161,7 @@ void CMenus::RenderDemoPlayer(CUIRect MainView) static int s_ResetButton = 0; if(DoButton_DemoPlayer_Sprite(&s_ResetButton, SPRITE_DEMOBUTTON_STOP, false, &Button)) { + m_pClient->OnReset(); DemoPlayer()->Pause(); DemoPlayer()->SetPos(0); } diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 9d1c8c13b..6c8eb2184 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -128,6 +128,9 @@ void CScoreboard::RenderSpectators(float x, float y, float w) void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const char *pTitle) { + if(Team == TEAM_SPECTATORS) + return; + //float ystart = y; float h = 750.0f; @@ -150,61 +153,20 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch float Offset = 80.0f; float DataOffset = 130; float tw = TextRender()->TextWidth(0, 48, pTitle, -1); + TextRender()->Text(0, x+10, y, 48, pTitle, -1); - if(Team == TEAM_SPECTATORS) - { - TextRender()->Text(0, x+w/2-tw/2, y, 48, pTitle, -1); - } - else - { - TextRender()->Text(0, x+10, y, 48, pTitle, -1); - if(str_comp_nocase(m_pServerInfo.m_aGameType, "DDRace")) - if(m_pClient->m_Snap.m_pGameobj) - { - char aBuf[128]; - int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue; - str_format(aBuf, sizeof(aBuf), "%d", Score); - tw = TextRender()->TextWidth(0, 48, aBuf, -1); - TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1); - } - } + if(str_comp_nocase(m_pServerInfo.m_aGameType, "DDRace")) + if(m_pClient->m_Snap.m_pGameobj) + { + char aBuf[128]; + int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue; + str_format(aBuf, sizeof(aBuf), "%d", Score); + tw = TextRender()->TextWidth(0, 48, aBuf, -1); + TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1); + } y += 54.0f; - // find players - const CNetObj_PlayerInfo *paPlayers[MAX_CLIENTS] = {0}; - int NumPlayers = 0; - for(int i = 0; i < Client()->SnapNumItems(IClient::SNAP_CURRENT); i++) - { - IClient::CSnapItem Item; - const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); - - if(Item.m_Type == NETOBJTYPE_PLAYERINFO) - { - const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; - if(pInfo->m_Team == Team) - { - paPlayers[NumPlayers] = pInfo; - if(++NumPlayers == MAX_CLIENTS) - break; - } - } - } - - // sort players - for(int k = 0; k < NumPlayers-1; k++) // ffs, bubblesort - { - for(int i = 0; i < NumPlayers-k-1; i++) - { - if((str_comp_nocase(m_pServerInfo.m_aGameType, "DDRace") && (paPlayers[i]->m_Score < paPlayers[i+1]->m_Score)) || (!str_comp_nocase(m_pServerInfo.m_aGameType, "DDRace") && (m_pClient->m_aClients[paPlayers[i]->m_ClientId].m_Score == 0 || (m_pClient->m_aClients[paPlayers[i]->m_ClientId].m_Score > m_pClient->m_aClients[paPlayers[i+1]->m_ClientId].m_Score && m_pClient->m_aClients[paPlayers[i+1]->m_ClientId].m_Score != 0)))) - { - const CNetObj_PlayerInfo *pTmp = paPlayers[i]; - paPlayers[i] = paPlayers[i+1]; - paPlayers[i+1] = pTmp; - } - } - } - // render headlines TextRender()->Text(0, x+10, y, 24.0f, Localize("Score"), -1); if(!str_comp_nocase(m_pServerInfo.m_aGameType, "DDRace")) @@ -224,7 +186,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch float TeeSizeMod = 1.0f; float TeeOffset = 0.0f; - if(NumPlayers > 13) + if(m_pClient->m_Snap.m_aTeamSize[Team] > 13) { FontSize = 30.0f; LineHeight = 40.0f; @@ -233,9 +195,11 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch } // render player scores - for(int i = 0; i < NumPlayers; i++) + for(int i = 0; i < MAX_CLIENTS; i++) { - const CNetObj_PlayerInfo *pInfo = paPlayers[i]; + const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_paInfoByScore[i]; + if(!pInfo || pInfo->m_Team != Team) + continue; // make sure that we render the correct team @@ -422,8 +386,8 @@ void CScoreboard::OnRender() else if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed) pText = Localize("Blue team wins!"); - float w = TextRender()->TextWidth(0, 92.0f, pText, -1); - TextRender()->Text(0, Width/2-w/2, 45, 92.0f, pText, -1); + float w = TextRender()->TextWidth(0, 86.0f, pText, -1); + TextRender()->Text(0, Width/2-w/2, 39, 86.0f, pText, -1); } RenderScoreboard(Width/2-w-20, 150.0f, w, TEAM_RED, Localize("Red team")); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index f64fa8e40..3dcaaad4b 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -631,6 +631,12 @@ void CGameClient::OnGameOver() Client()->AutoScreenshot_Start(); } +void CGameClient::OnStartGame() +{ + if(Client()->State() != IClient::STATE_DEMOPLAYBACK) + Client()->DemoRecorder_HandleAutoStart(); +} + void CGameClient::OnRconLine(const char *pLine) { m_pGameConsole->PrintLine(CGameConsole::CONSOLETYPE_REMOTE, pLine); @@ -821,6 +827,8 @@ void CGameClient::OnNewSnapshot() m_Snap.m_pGameobj = (CNetObj_Game *)pData; if(s_GameOver == 0 && m_Snap.m_pGameobj->m_GameOver != 0) OnGameOver(); + else if(s_GameOver != 0 && m_Snap.m_pGameobj->m_GameOver == 0) + OnStartGame(); s_GameOver = m_Snap.m_pGameobj->m_GameOver; } else if(Item.m_Type == NETOBJTYPE_FLAG) @@ -846,6 +854,21 @@ void CGameClient::OnNewSnapshot() } else m_Snap.m_Spectate = true; + + // sort player infos by score + mem_copy(m_Snap.m_paInfoByScore, m_Snap.m_paPlayerInfos, sizeof(m_Snap.m_paInfoByScore)); + for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort + { + for(int i = 0; i < MAX_CLIENTS-k-1; i++) + { + if(m_Snap.m_paInfoByScore[i+1] && (!m_Snap.m_paInfoByScore[i] || m_Snap.m_paInfoByScore[i]->m_Score < m_Snap.m_paInfoByScore[i+1]->m_Score)) + { + const CNetObj_PlayerInfo *pTmp = m_Snap.m_paInfoByScore[i]; + m_Snap.m_paInfoByScore[i] = m_Snap.m_paInfoByScore[i+1]; + m_Snap.m_paInfoByScore[i+1] = pTmp; + } + } + } CTuningParams StandardTuning; CServerInfo CurrentServerInfo; diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index c6a487f78..8cda6a7ca 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -187,6 +187,7 @@ public: virtual void OnEnterGame(); virtual void OnRconLine(const char *pLine); virtual void OnGameOver(); + virtual void OnStartGame(); virtual const char *GetItemName(int Type); virtual const char *Version(); diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index b78c57057..9ac91d459 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -186,38 +186,38 @@ void CCharacter::HandleNinja() // check if we Hit anything along the way { - CCharacter *aEnts[64]; + CCharacter *apEnts[64]; vec2 Dir = m_Pos - OldPos; float Radius = m_ProximityRadius * 2.0f; vec2 Center = OldPos + Dir * 0.5f; - int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, 64, NETOBJTYPE_CHARACTER); + int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)apEnts, 64, NETOBJTYPE_CHARACTER); for (int i = 0; i < Num; ++i) { - if (aEnts[i] == this) + if (apEnts[i] == this) continue; // make sure we haven't Hit this object before bool bAlreadyHit = false; for (int j = 0; j < m_NumObjectsHit; j++) { - if (m_apHitObjects[j] == aEnts[i]) + if (m_apHitObjects[j] == apEnts[i]) bAlreadyHit = true; } if (bAlreadyHit) continue; // check so we are sufficiently close - if (distance(aEnts[i]->m_Pos, m_Pos) > (m_ProximityRadius * 2.0f)) + if (distance(apEnts[i]->m_Pos, m_Pos) > (m_ProximityRadius * 2.0f)) continue; // Hit a m_pPlayer, give him damage and stuffs... - GameServer()->CreateSound(aEnts[i]->m_Pos, SOUND_NINJA_HIT); + GameServer()->CreateSound(apEnts[i]->m_Pos, SOUND_NINJA_HIT); // set his velocity to fast upward (for now) if(m_NumObjectsHit < 10) - m_apHitObjects[m_NumObjectsHit++] = aEnts[i]; + m_apHitObjects[m_NumObjectsHit++] = apEnts[i]; - aEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA); + apEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA); } } @@ -329,39 +329,39 @@ void CCharacter::FireWeapon() if (!g_Config.m_SvHit) break; - CCharacter *aEnts[64]; + CCharacter *apEnts[64]; int Hits = 0; - int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)aEnts, + int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts, 64, NETOBJTYPE_CHARACTER); for (int i = 0; i < Num; ++i) { - CCharacter *Target = aEnts[i]; + CCharacter *pTarget = apEnts[i]; //for DDRace mod or any other mod, which needs hammer hits through the wall remove second condition - if ((Target == this || !CanCollide(Target->GetPlayer()->GetCID())) /*|| GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL)*/) + if ((pTarget == this || !CanCollide(pTarget->GetPlayer()->GetCID())) /*|| GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL)*/) continue; // set his velocity to fast upward (for now) GameServer()->CreateHammerHit(m_Pos, Teams()->TeamMask(Team())); - aEnts[i]->TakeDamage(vec2(0.f, -1.f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon); + apEnts[i]->TakeDamage(vec2(0.f, -1.f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon); vec2 Dir; - if (length(Target->m_Pos - m_Pos) > 0.0f) - Dir = normalize(Target->m_Pos - m_Pos); + if (length(pTarget->m_Pos - m_Pos) > 0.0f) + Dir = normalize(pTarget->m_Pos - m_Pos); else Dir = vec2(0.f, -1.f); - vec2 Temp = Target->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f * (m_HammerType + 1); - if(Temp.x > 0 && ((Target->m_TileIndex == TILE_STOP && Target->m_TileFlags == ROTATION_270) || (Target->m_TileIndexL == TILE_STOP && Target->m_TileFlagsL == ROTATION_270) || (Target->m_TileIndexL == TILE_STOPS && (Target->m_TileFlagsL == ROTATION_90 || Target->m_TileFlagsL ==ROTATION_270)) || (Target->m_TileIndexL == TILE_STOPA) || (Target->m_TileFIndex == TILE_STOP && Target->m_TileFFlags == ROTATION_270) || (Target->m_TileFIndexL == TILE_STOP && Target->m_TileFFlagsL == ROTATION_270) || (Target->m_TileFIndexL == TILE_STOPS && (Target->m_TileFFlagsL == ROTATION_90 || Target->m_TileFFlagsL == ROTATION_270)) || (Target->m_TileFIndexL == TILE_STOPA) || (Target->m_TileSIndex == TILE_STOP && Target->m_TileSFlags == ROTATION_270) || (Target->m_TileSIndexL == TILE_STOP && Target->m_TileSFlagsL == ROTATION_270) || (Target->m_TileSIndexL == TILE_STOPS && (Target->m_TileSFlagsL == ROTATION_90 || Target->m_TileSFlagsL == ROTATION_270)) || (Target->m_TileSIndexL == TILE_STOPA))) + vec2 Temp = pTarget->m_Core.m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f * (m_HammerType + 1); + if(Temp.x > 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_270) || (pTarget->m_TileIndexL == TILE_STOP && pTarget->m_TileFlagsL == ROTATION_270) || (pTarget->m_TileIndexL == TILE_STOPS && (pTarget->m_TileFlagsL == ROTATION_90 || pTarget->m_TileFlagsL ==ROTATION_270)) || (pTarget->m_TileIndexL == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_270) || (pTarget->m_TileFIndexL == TILE_STOP && pTarget->m_TileFFlagsL == ROTATION_270) || (pTarget->m_TileFIndexL == TILE_STOPS && (pTarget->m_TileFFlagsL == ROTATION_90 || pTarget->m_TileFFlagsL == ROTATION_270)) || (pTarget->m_TileFIndexL == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_270) || (pTarget->m_TileSIndexL == TILE_STOP && pTarget->m_TileSFlagsL == ROTATION_270) || (pTarget->m_TileSIndexL == TILE_STOPS && (pTarget->m_TileSFlagsL == ROTATION_90 || pTarget->m_TileSFlagsL == ROTATION_270)) || (pTarget->m_TileSIndexL == TILE_STOPA))) Temp.x = 0; - if(Temp.x < 0 && ((Target->m_TileIndex == TILE_STOP && Target->m_TileFlags == ROTATION_90) || (Target->m_TileIndexR == TILE_STOP && Target->m_TileFlagsR == ROTATION_90) || (Target->m_TileIndexR == TILE_STOPS && (Target->m_TileFlagsR == ROTATION_90 || Target->m_TileFlagsR == ROTATION_270)) || (Target->m_TileIndexR == TILE_STOPA) || (Target->m_TileFIndex == TILE_STOP && Target->m_TileFFlags == ROTATION_90) || (Target->m_TileFIndexR == TILE_STOP && Target->m_TileFFlagsR == ROTATION_90) || (Target->m_TileFIndexR == TILE_STOPS && (Target->m_TileFFlagsR == ROTATION_90 || Target->m_TileFFlagsR == ROTATION_270)) || (Target->m_TileFIndexR == TILE_STOPA) || (Target->m_TileSIndex == TILE_STOP && Target->m_TileSFlags == ROTATION_90) || (Target->m_TileSIndexR == TILE_STOP && Target->m_TileSFlagsR == ROTATION_90) || (Target->m_TileSIndexR == TILE_STOPS && (Target->m_TileSFlagsR == ROTATION_90 || Target->m_TileSFlagsR == ROTATION_270)) || (Target->m_TileSIndexR == TILE_STOPA))) + if(Temp.x < 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_90) || (pTarget->m_TileIndexR == TILE_STOP && pTarget->m_TileFlagsR == ROTATION_90) || (pTarget->m_TileIndexR == TILE_STOPS && (pTarget->m_TileFlagsR == ROTATION_90 || pTarget->m_TileFlagsR == ROTATION_270)) || (pTarget->m_TileIndexR == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_90) || (pTarget->m_TileFIndexR == TILE_STOP && pTarget->m_TileFFlagsR == ROTATION_90) || (pTarget->m_TileFIndexR == TILE_STOPS && (pTarget->m_TileFFlagsR == ROTATION_90 || pTarget->m_TileFFlagsR == ROTATION_270)) || (pTarget->m_TileFIndexR == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_90) || (pTarget->m_TileSIndexR == TILE_STOP && pTarget->m_TileSFlagsR == ROTATION_90) || (pTarget->m_TileSIndexR == TILE_STOPS && (pTarget->m_TileSFlagsR == ROTATION_90 || pTarget->m_TileSFlagsR == ROTATION_270)) || (pTarget->m_TileSIndexR == TILE_STOPA))) Temp.x = 0; - if(Temp.y < 0 && ((Target->m_TileIndex == TILE_STOP && Target->m_TileFlags == ROTATION_180) || (Target->m_TileIndexB == TILE_STOP && Target->m_TileFlagsB == ROTATION_180) || (Target->m_TileIndexB == TILE_STOPS && (Target->m_TileFlagsB == ROTATION_0 || Target->m_TileFlagsB == ROTATION_180)) || (Target->m_TileIndexB == TILE_STOPA) || (Target->m_TileFIndex == TILE_STOP && Target->m_TileFFlags == ROTATION_180) || (Target->m_TileFIndexB == TILE_STOP && Target->m_TileFFlagsB == ROTATION_180) || (Target->m_TileFIndexB == TILE_STOPS && (Target->m_TileFFlagsB == ROTATION_0 || Target->m_TileFFlagsB == ROTATION_180)) || (Target->m_TileFIndexB == TILE_STOPA) || (Target->m_TileSIndex == TILE_STOP && Target->m_TileSFlags == ROTATION_180) || (Target->m_TileSIndexB == TILE_STOP && Target->m_TileSFlagsB == ROTATION_180) || (Target->m_TileSIndexB == TILE_STOPS && (Target->m_TileSFlagsB == ROTATION_0 || Target->m_TileSFlagsB == ROTATION_180)) || (Target->m_TileSIndexB == TILE_STOPA))) + if(Temp.y < 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_180) || (pTarget->m_TileIndexB == TILE_STOP && pTarget->m_TileFlagsB == ROTATION_180) || (pTarget->m_TileIndexB == TILE_STOPS && (pTarget->m_TileFlagsB == ROTATION_0 || pTarget->m_TileFlagsB == ROTATION_180)) || (pTarget->m_TileIndexB == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_180) || (pTarget->m_TileFIndexB == TILE_STOP && pTarget->m_TileFFlagsB == ROTATION_180) || (pTarget->m_TileFIndexB == TILE_STOPS && (pTarget->m_TileFFlagsB == ROTATION_0 || pTarget->m_TileFFlagsB == ROTATION_180)) || (pTarget->m_TileFIndexB == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_180) || (pTarget->m_TileSIndexB == TILE_STOP && pTarget->m_TileSFlagsB == ROTATION_180) || (pTarget->m_TileSIndexB == TILE_STOPS && (pTarget->m_TileSFlagsB == ROTATION_0 || pTarget->m_TileSFlagsB == ROTATION_180)) || (pTarget->m_TileSIndexB == TILE_STOPA))) Temp.y = 0; - if(Temp.y > 0 && ((Target->m_TileIndex == TILE_STOP && Target->m_TileFlags == ROTATION_0) || (Target->m_TileIndexT == TILE_STOP && Target->m_TileFlagsT == ROTATION_0) || (Target->m_TileIndexT == TILE_STOPS && (Target->m_TileFlagsT == ROTATION_0 || Target->m_TileFlagsT == ROTATION_180)) || (Target->m_TileIndexT == TILE_STOPA) || (Target->m_TileFIndex == TILE_STOP && Target->m_TileFFlags == ROTATION_0) || (Target->m_TileFIndexT == TILE_STOP && Target->m_TileFFlagsT == ROTATION_0) || (Target->m_TileFIndexT == TILE_STOPS && (Target->m_TileFFlagsT == ROTATION_0 || Target->m_TileFFlagsT == ROTATION_180)) || (Target->m_TileFIndexT == TILE_STOPA) || (Target->m_TileSIndex == TILE_STOP && Target->m_TileSFlags == ROTATION_0) || (Target->m_TileSIndexT == TILE_STOP && Target->m_TileSFlagsT == ROTATION_0) || (Target->m_TileSIndexT == TILE_STOPS && (Target->m_TileSFlagsT == ROTATION_0 || Target->m_TileSFlagsT == ROTATION_180)) || (Target->m_TileSIndexT == TILE_STOPA))) + if(Temp.y > 0 && ((pTarget->m_TileIndex == TILE_STOP && pTarget->m_TileFlags == ROTATION_0) || (pTarget->m_TileIndexT == TILE_STOP && pTarget->m_TileFlagsT == ROTATION_0) || (pTarget->m_TileIndexT == TILE_STOPS && (pTarget->m_TileFlagsT == ROTATION_0 || pTarget->m_TileFlagsT == ROTATION_180)) || (pTarget->m_TileIndexT == TILE_STOPA) || (pTarget->m_TileFIndex == TILE_STOP && pTarget->m_TileFFlags == ROTATION_0) || (pTarget->m_TileFIndexT == TILE_STOP && pTarget->m_TileFFlagsT == ROTATION_0) || (pTarget->m_TileFIndexT == TILE_STOPS && (pTarget->m_TileFFlagsT == ROTATION_0 || pTarget->m_TileFFlagsT == ROTATION_180)) || (pTarget->m_TileFIndexT == TILE_STOPA) || (pTarget->m_TileSIndex == TILE_STOP && pTarget->m_TileSFlags == ROTATION_0) || (pTarget->m_TileSIndexT == TILE_STOP && pTarget->m_TileSFlagsT == ROTATION_0) || (pTarget->m_TileSIndexT == TILE_STOPS && (pTarget->m_TileSFlagsT == ROTATION_0 || pTarget->m_TileSFlagsT == ROTATION_180)) || (pTarget->m_TileSIndexT == TILE_STOPA))) Temp.y = 0; - Target->m_Core.m_Vel = Temp; - Target->UnFreeze(); + pTarget->m_Core.m_Vel = Temp; + pTarget->UnFreeze(); Hits++; } @@ -373,7 +373,7 @@ void CCharacter::FireWeapon() case WEAPON_GUN: { - CProjectile *Proj = new CProjectile + CProjectile *pProj = new CProjectile ( GameWorld(), WEAPON_GUN,//Type @@ -390,7 +390,7 @@ void CCharacter::FireWeapon() // pack the Projectile and send it to the client Directly CNetObj_Projectile p; - Proj->FillInfo(&p); + pProj->FillInfo(&p); CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE); Msg.AddInt(1); @@ -418,7 +418,7 @@ void CCharacter::FireWeapon() a += Spreading[i+2]; float v = 1-(absolute(i)/(float)ShotSpread); float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v); - CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_SHOTGUN, + CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN, m_pPlayer->GetCID(), ProjStartPos, vec2(cosf(a), sinf(a))*Speed, @@ -427,7 +427,7 @@ void CCharacter::FireWeapon() // pack the Projectile and send it to the client Directly CNetObj_Projectile p; - Proj->FillInfo(&p); + pProj->FillInfo(&p); for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); @@ -440,7 +440,7 @@ void CCharacter::FireWeapon() case WEAPON_GRENADE: { - CProjectile *Proj = new CProjectile + CProjectile *pProj = new CProjectile ( GameWorld(), WEAPON_GRENADE,//Type @@ -457,7 +457,7 @@ void CCharacter::FireWeapon() // pack the Projectile and send it to the client Directly CNetObj_Projectile p; - Proj->FillInfo(&p); + pProj->FillInfo(&p); CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE); Msg.AddInt(1); @@ -1166,15 +1166,15 @@ void CCharacter::HandleTiles(int Index) m_Core.m_Vel = vec2(0,0); return; } - // handle death-tiles + // handle death-tiles and leaving gamelayer if((GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || - GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || GameServer()->Collision()->GetFCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || GameServer()->Collision()->GetFCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || GameServer()->Collision()->GetFCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || - GameServer()->Collision()->GetFCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH)&& + GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || + GameLayerClipped(m_Pos)) && !m_Super) { Die(m_pPlayer->GetCID(), WEAPON_WORLD); diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index e5737bb03..80fc0d407 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -120,7 +120,7 @@ void CProjectile::Tick() { TeamMask = OwnerChar->Teams()->TeamMask( OwnerChar->Team()); } - if( ((TargetChr && (g_Config.m_SvHit || m_Owner == -1 || TargetChr == OwnerChar)) || Collide) && !isWeaponCollide)//TODO:TEAM + if( ((TargetChr && (g_Config.m_SvHit || m_Owner == -1 || TargetChr == OwnerChar)) || Collide || GameLayerClipped(CurPos)) && !isWeaponCollide)//TODO:TEAM { if(m_Explosive/*??*/ && (!TargetChr || (TargetChr && !m_Freeze))) { diff --git a/src/game/server/entity.cpp b/src/game/server/entity.cpp index 1f37d167d..5241c06b1 100644 --- a/src/game/server/entity.cpp +++ b/src/game/server/entity.cpp @@ -50,3 +50,9 @@ int CEntity::NetworkClipped(int SnappingClient, vec2 CheckPos) return 1; return 0; } + +bool CEntity::GameLayerClipped(vec2 CheckPos) +{ + return round(CheckPos.x)/32 < -200 || round(CheckPos.x)/32 > GameServer()->Collision()->GetWidth()+200 || + round(CheckPos.y)/32 < -200 || round(CheckPos.y)/32 > GameServer()->Collision()->GetHeight()+200 ? true : false; +} diff --git a/src/game/server/entity.h b/src/game/server/entity.h index 3e00991de..237822c73 100644 --- a/src/game/server/entity.h +++ b/src/game/server/entity.h @@ -143,7 +143,8 @@ public: */ int NetworkClipped(int SnappingClient); int NetworkClipped(int SnappingClient, vec2 CheckPos); - + + bool GameLayerClipped(vec2 CheckPos); /* Variable: proximity_radius diff --git a/src/game/server/gamemodes/ctf.cpp b/src/game/server/gamemodes/ctf.cpp index 5ac201720..ed0e111e5 100644 --- a/src/game/server/gamemodes/ctf.cpp +++ b/src/game/server/gamemodes/ctf.cpp @@ -92,8 +92,8 @@ void CGameControllerCTF::Tick() if(!F) continue; - // flag hits death-tile, reset it - if(GameServer()->Collision()->GetCollisionAt(F->m_Pos.x, F->m_Pos.y)&CCollision::COLFLAG_DEATH) + // flag hits death-tile or left the game layer, reset it + if(GameServer()->Collision()->GetCollisionAt(F->m_Pos.x, F->m_Pos.y)&CCollision::COLFLAG_DEATH || F->GameLayerClipped(F->m_Pos)) { GameServer()->CreateSoundGlobal(SOUND_CTF_RETURN); F->Reset(); @@ -213,4 +213,4 @@ void CGameControllerCTF::Tick() } } } -*/ \ No newline at end of file +*/