From 41b8022aa1a941a4b2f3095dd4f8600daf4cd168 Mon Sep 17 00:00:00 2001 From: oy Date: Thu, 6 Jan 2011 23:21:51 +0100 Subject: [PATCH 01/17] record a new demo when a game ends. Closes #358 --- src/engine/client.h | 1 + src/engine/client/client.cpp | 1 + src/game/client/gameclient.cpp | 8 ++++++++ src/game/client/gameclient.h | 1 + 4 files changed, 11 insertions(+) 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 aab6e68f5..d67e33320 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -2154,6 +2154,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/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 45bd7ae3d..2bebf4861 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -591,6 +591,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); @@ -781,6 +787,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) diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 5ee2c989a..99e64028a 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -181,6 +181,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(); From 26f7c67895dd49e8ed91bf7a4c67aff485119087 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 7 Jan 2011 19:33:29 +0100 Subject: [PATCH 02/17] fixed console parsing when using the exec command. Closes #381 --- src/engine/shared/console.cpp | 21 +++++++++++---------- src/engine/shared/console.h | 32 +++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/engine/shared/console.cpp b/src/engine/shared/console.cpp index 2a290cb37..987e252b9 100644 --- a/src/engine/shared/console.cpp +++ b/src/engine/shared/console.cpp @@ -217,7 +217,7 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) { 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; @@ -245,24 +245,24 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) 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)) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Invalid arguments... Usage: %s %s", pCommand->m_pName, pCommand->m_pParams); @@ -270,18 +270,19 @@ void CConsole::ExecuteLineStroked(int Stroke, const char *pStr) } 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 - pCommand->m_pfnCallback(pResult, pCommand->m_pUserData); + pCommand->m_pfnCallback(&Result, pCommand->m_pUserData); } } else if(Stroke) { 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); Print(OUTPUT_LEVEL_STANDARD, "Console", aBuf); } @@ -569,7 +570,7 @@ void CConsole::StoreCommands(bool Store) { 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); m_ExecutionQueue.Reset(); } diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 5cacfd90b..30f53cf71 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -66,6 +66,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(int i = 0; i < Other.m_NumArgs; ++i) + m_apArgs[i] = Other.m_apArgs[i] + Offset; + } + return *this; + } void AddArgument(const char *pArg) { @@ -97,14 +120,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; From df47aedbfebd9d5ab71cb8aeeede83a77c36de95 Mon Sep 17 00:00:00 2001 From: oy Date: Sat, 8 Jan 2011 11:34:19 +0100 Subject: [PATCH 03/17] reset flags and projectiles when leaving the game layer too much. Closes #385 --- src/game/server/entities/character.cpp | 12 +++--------- src/game/server/entities/projectile.cpp | 2 +- src/game/server/entity.cpp | 6 ++++++ src/game/server/entity.h | 3 ++- src/game/server/gamemodes/ctf.cpp | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index e6bb06800..77755925a 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -544,18 +544,12 @@ void CCharacter::Tick() m_Core.m_Input = m_Input; m_Core.Tick(true); - // 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) - { - Die(m_pPlayer->GetCID(), WEAPON_WORLD); - } - - // kill player when leaving gamelayer - if((int)m_Pos.x/32 < -200 || (int)m_Pos.x/32 > GameServer()->Collision()->GetWidth()+200 || - (int)m_Pos.y/32 < -200 || (int)m_Pos.y/32 > GameServer()->Collision()->GetHeight()+200) + GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH || + GameLayerClipped(m_Pos)) { Die(m_pPlayer->GetCID(), WEAPON_WORLD); } diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index 5b3bc482e..f5c376a2f 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -67,7 +67,7 @@ void CProjectile::Tick() m_LifeSpan--; - if(TargetChr || Collide || m_LifeSpan < 0) + if(TargetChr || Collide || m_LifeSpan < 0 || GameLayerClipped(CurPos)) { if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE) GameServer()->CreateSound(CurPos, m_SoundImpact); 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 b088864d3..dc50daca7 100644 --- a/src/game/server/entity.h +++ b/src/game/server/entity.h @@ -137,7 +137,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 18905dbfe..f6681ff69 100644 --- a/src/game/server/gamemodes/ctf.cpp +++ b/src/game/server/gamemodes/ctf.cpp @@ -91,8 +91,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(); From 91f642fac2362b03c5246f76883dd2eadc54abdd Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 9 Jan 2011 23:25:07 +0100 Subject: [PATCH 04/17] fixed cut off broadcast. Closes #398 --- src/engine/client/text.cpp | 17 ++++++++--------- src/game/client/components/broadcast.cpp | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) 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/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index a4940ed76..c262fff0a 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -23,7 +23,7 @@ void CBroadcast::OnRender() { 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); } } From a9f7f3a3eaf63c14d2d34a452a373714cfce20a8 Mon Sep 17 00:00:00 2001 From: Patafix Date: Sun, 9 Jan 2011 20:53:19 +0100 Subject: [PATCH 05/17] just formatting --- src/game/server/entities/character.cpp | 28 +++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 77755925a..0a3dd87bd 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -289,30 +289,30 @@ void CCharacter::FireWeapon() m_NumObjectsHit = 0; GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE); - 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 race mod or any other mod, which needs hammer hits through the wall remove second condition - if ((Target == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL)) + if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL)) continue; // set his velocity to fast upward (for now) GameServer()->CreateHammerHit(m_Pos); - aEnts[i]->TakeDamage(vec2(0.f, -1.f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon); + pTarget->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); - Target->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; + pTarget->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * 10.0f; Hits++; } @@ -324,7 +324,7 @@ void CCharacter::FireWeapon() case WEAPON_GUN: { - CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GUN, + CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GUN, m_pPlayer->GetCID(), ProjStartPos, Direction, @@ -333,7 +333,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); @@ -359,7 +359,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, @@ -368,7 +368,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]); @@ -381,7 +381,7 @@ void CCharacter::FireWeapon() case WEAPON_GRENADE: { - CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GRENADE, + CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GRENADE, m_pPlayer->GetCID(), ProjStartPos, Direction, @@ -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); From 9358b2411313ece2e73766acd1c7bd3a44c8bf8e Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 9 Jan 2011 23:42:37 +0100 Subject: [PATCH 06/17] reset demo player on end and when pressing the stop button. Closes #401 --- src/game/client/components/menus_demo.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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); } From 9819163c5f86c45283306e87fed9353836c7fd6b Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 10 Jan 2011 00:18:30 +0100 Subject: [PATCH 07/17] fixed some overlapping in the server browser. Closes #376 --- src/game/client/components/menus_browser.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 08e5a3bc8..9f6c23dc6 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -493,6 +493,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); @@ -540,15 +541,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); } @@ -574,11 +581,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; From 8f999837c674b83fb813ef7f394b4c611d08311b Mon Sep 17 00:00:00 2001 From: oy Date: Mon, 10 Jan 2011 00:58:03 +0100 Subject: [PATCH 08/17] improved the count down timer. Closes #391 --- src/game/client/components/hud.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 1f57558ea..093e4f6cb 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -49,7 +49,14 @@ void CHud::RenderGameTimer() str_format(Buf, sizeof(Buf), "%d:%02d", Time/60, Time%60); float FontSize = 10.0f; float w = TextRender()->TextWidth(0, FontSize, Buf, -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); } } From 4a79e575a0adbce71e0a99d7c0824d73906bf06c Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 11 Jan 2011 00:57:44 +0100 Subject: [PATCH 09/17] fixed a compiler warning --- src/engine/shared/console.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/shared/console.h b/src/engine/shared/console.h index 30f53cf71..a276751ae 100644 --- a/src/engine/shared/console.h +++ b/src/engine/shared/console.h @@ -84,7 +84,7 @@ class CConsole : public IConsole mem_copy(m_aStringStorage, Other.m_aStringStorage, sizeof(m_aStringStorage)); m_pArgsStart = Other.m_pArgsStart + Offset; m_pCommand = Other.m_pCommand + Offset; - for(int i = 0; i < Other.m_NumArgs; ++i) + for(unsigned i = 0; i < Other.m_NumArgs; ++i) m_apArgs[i] = Other.m_apArgs[i] + Offset; } return *this; From 308dd0304d5acd3ffeaa0dc92857fa937455f605 Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 11 Jan 2011 01:09:46 +0100 Subject: [PATCH 10/17] added Romanian translation by kneekoo --- data/languages/bosnian.txt | 3 + data/languages/czech.txt | 3 + data/languages/dutch.txt | 3 + data/languages/finnish.txt | 3 + data/languages/french.txt | 6 +- data/languages/german.txt | 3 + data/languages/index.txt | 3 + data/languages/italian.txt | 3 + data/languages/polish.txt | 3 + data/languages/portuguese.txt | 3 + data/languages/romanian.txt | 970 ++++++++++++++++++++++++++++++++++ data/languages/russian.txt | 3 + data/languages/serbian.txt | 3 + data/languages/swedish.txt | 3 + data/languages/ukrainian.txt | 3 + 15 files changed, 1012 insertions(+), 3 deletions(-) create mode 100644 data/languages/romanian.txt diff --git a/data/languages/bosnian.txt b/data/languages/bosnian.txt index ebad82e7e..8f183bb19 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 80db8b7e7..0383f26e0 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 f27655fa1..fc5d2a8db 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -963,5 +963,8 @@ no limit Name plates size == +Unable to delete the demo +== + ##### old translations ##### diff --git a/data/languages/finnish.txt b/data/languages/finnish.txt index a4638b17a..6c240eef9 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 c8176bbf8..febb632d3 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 876b605af..ca1c50070 100644 --- a/data/languages/german.txt +++ b/data/languages/german.txt @@ -963,5 +963,8 @@ no limit Name plates size == +Unable to delete the demo +== + ##### old translations ##### 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 a8b04e22a..e93ac0bef 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 79eb8db67..2fee6abcc 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 9e09864e4..eb1770f02 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 3553ebd55..8ae65a8c8 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 5493c516a..e3d106de3 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 ecb7cea6e..b779995f0 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 8586928ba..477bed262 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 == From 3f9708b263d101e5df5219f0e032da616ddfe107 Mon Sep 17 00:00:00 2001 From: Choupom Date: Sun, 9 Jan 2011 12:26:02 +0100 Subject: [PATCH 11/17] added some .gitignore entries --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 681510f2d..42f72257f 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* From b60d6deb513d217727c92972061ce7afcb072c9a Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 11 Jan 2011 23:03:01 +0100 Subject: [PATCH 12/17] made m_paInfoByScore within gameclient's snap state work and cleaned up render scoreboard --- src/game/client/components/scoreboard.cpp | 67 +++++------------------ src/game/client/gameclient.cpp | 15 +++++ 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 5556861c9..2292f40eb 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -119,6 +119,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; @@ -139,61 +142,19 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch } float tw = TextRender()->TextWidth(0, 48, pTitle, -1); + TextRender()->Text(0, x+10, y, 48, pTitle, -1); - if(Team == TEAM_SPECTATORS) + if(m_pClient->m_Snap.m_pGameobj) { - TextRender()->Text(0, x+w/2-tw/2, y, 48, pTitle, -1); - } - else - { - TextRender()->Text(0, x+10, y, 48, pTitle, -1); - - 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); - } + 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(paPlayers[i]->m_Score < paPlayers[i+1]->m_Score) - { - 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); TextRender()->Text(0, x+125, y, 24.0f, Localize("Name"), -1); @@ -205,7 +166,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; @@ -214,9 +175,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 diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 2bebf4861..9a05cc88d 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -814,6 +814,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; From d79fd3d4c0cd6fce9bfd7f1e91eafce87a09b5a8 Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 12 Jan 2011 01:01:05 +0100 Subject: [PATCH 13/17] added dm score hud. Closes #356 --- src/game/client/components/hud.cpp | 171 ++++++++++++++++++++--------- 1 file changed, 119 insertions(+), 52 deletions(-) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 093e4f6cb..9f49952d9 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -73,66 +73,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); + } + } } } From 1f552379199e4811c073f2bc14d677ef3706f73d Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 12 Jan 2011 01:10:40 +0100 Subject: [PATCH 14/17] made the end game message in team games a bit smaller so it doesn't overlap the scoreboard. Closes #406 --- src/game/client/components/scoreboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index 2292f40eb..5fb2395fc 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -313,8 +313,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")); From 3f4556a861168419a646a5f3353529c34aec1409 Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 12 Jan 2011 01:18:07 +0100 Subject: [PATCH 15/17] hide the broadcast when the scoreboard is active. Closes #408 --- src/game/client/components/broadcast.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index c262fff0a..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,6 +19,9 @@ 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) From b94c70d351b1c366b20b3a87b3dacf11070b3412 Mon Sep 17 00:00:00 2001 From: oy Date: Wed, 12 Jan 2011 01:33:16 +0100 Subject: [PATCH 16/17] close the scoreboard when opening the menu in the demo player. Closes #407 --- src/game/client/components/menus.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 257c278bc..d70e0b880 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1103,6 +1103,10 @@ void CMenus::SetActive(bool Active) m_pClient->OnRelease(); } } + else if(Client()->State() == IClient::STATE_DEMOPLAYBACK) + { + m_pClient->OnRelease(); + } } void CMenus::OnReset() From 5483eb66294aabea76624659886a7c39a0758e66 Mon Sep 17 00:00:00 2001 From: Sworddragon Date: Mon, 10 Jan 2011 02:08:50 +0100 Subject: [PATCH 17/17] Fixed encoding error --- scripts/update_localization.py | 35 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) 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))