diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/client/components/console.cpp | 85 | ||||
| -rw-r--r-- | src/game/client/components/console.h | 8 | ||||
| -rw-r--r-- | src/game/client/components/hud.cpp | 77 | ||||
| -rw-r--r-- | src/game/client/components/items.cpp | 2 | ||||
| -rw-r--r-- | src/game/client/components/maplayers.cpp | 2 | ||||
| -rw-r--r-- | src/game/client/components/menus.h | 1 | ||||
| -rw-r--r-- | src/game/client/components/menus_browser.cpp | 12 | ||||
| -rw-r--r-- | src/game/client/components/menus_demo.cpp | 36 | ||||
| -rw-r--r-- | src/game/client/components/players.cpp | 2 | ||||
| -rw-r--r-- | src/game/editor/ed_editor.cpp | 141 | ||||
| -rw-r--r-- | src/game/editor/ed_popups.cpp | 5 | ||||
| -rw-r--r-- | src/game/server/entities/character.cpp | 16 | ||||
| -rw-r--r-- | src/game/server/gamecontroller.cpp | 3 |
13 files changed, 271 insertions, 119 deletions
diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index b323ab48..cb8c31ce 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -1,5 +1,6 @@ //#include "gc_console.h" #include <math.h> +#include <time.h> #include <game/generated/client_data.h> @@ -9,6 +10,7 @@ #include <engine/shared/config.h> #include <engine/graphics.h> #include <engine/textrender.h> +#include <engine/storage.h> #include <engine/keys.h> #include <engine/console.h> @@ -51,6 +53,7 @@ CGameConsole::CInstance::CInstance(int Type) m_aCompletionBuffer[0] = 0; m_CompletionChosen = -1; + m_CompletionRenderOffset = 0.0f; m_pCommand = 0x0; } @@ -60,6 +63,12 @@ void CGameConsole::CInstance::Init(CGameConsole *pGameConsole) m_pGameConsole = pGameConsole; }; +void CGameConsole::CInstance::ClearBacklog() +{ + m_Backlog.Init(); + m_BacklogActPage = 0; +} + void CGameConsole::CInstance::ExecuteLine(const char *pLine) { if(m_Type == 0) @@ -180,11 +189,11 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event) char aBuf[64] = {0}; const char *pSrc = GetString(); int i = 0; - for(; i < (int)sizeof(aBuf) && *pSrc && *pSrc != ' ' && *pSrc != ' '; i++, pSrc++) + for(; i < (int)sizeof(aBuf)-1 && *pSrc && *pSrc != ' '; i++, pSrc++) aBuf[i] = *pSrc; aBuf[i] = 0; - m_pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf); + m_pCommand = m_pGameConsole->m_pConsole->GetCommandInfo(aBuf, m_CompletionFlagmask); } } } @@ -241,6 +250,8 @@ struct CRenderInfo const char *m_pCurrentCmd; int m_WantedCompletion; int m_EnumCount; + float m_Offset; + float m_Width; }; void CGameConsole::PossibleCommandsRenderCallback(const char *pStr, void *pUser) @@ -256,6 +267,12 @@ void CGameConsole::PossibleCommandsRenderCallback(const char *pStr, void *pUser) pInfo->m_pSelf->RenderTools()->DrawRoundRect(pInfo->m_Cursor.m_X-3, pInfo->m_Cursor.m_Y, tw+5, pInfo->m_Cursor.m_FontSize+4, pInfo->m_Cursor.m_FontSize/3); pInfo->m_pSelf->Graphics()->QuadsEnd(); + // scroll when out of sight + if(pInfo->m_Cursor.m_X < 3.0f) + pInfo->m_Offset = 0.0f; + else if(pInfo->m_Cursor.m_X+tw > pInfo->m_Width) + pInfo->m_Offset -= pInfo->m_Width/2; + pInfo->m_pSelf->TextRender()->TextColor(0.05f, 0.05f, 0.05f,1); pInfo->m_pSelf->TextRender()->TextEx(&pInfo->m_Cursor, pStr, -1); } @@ -386,8 +403,10 @@ void CGameConsole::OnRender() Info.m_pSelf = this; Info.m_WantedCompletion = pConsole->m_CompletionChosen; Info.m_EnumCount = 0; + Info.m_Offset = pConsole->m_CompletionRenderOffset; + Info.m_Width = Screen.w; Info.m_pCurrentCmd = pConsole->m_aCompletionBuffer; - TextRender()->SetCursor(&Info.m_Cursor, x, y+12.0f, FontSize, TEXTFLAG_RENDER); + TextRender()->SetCursor(&Info.m_Cursor, x+Info.m_Offset, y+12.0f, FontSize, TEXTFLAG_RENDER); const char *pPrompt = "> "; if(m_ConsoleType) @@ -438,6 +457,7 @@ void CGameConsole::OnRender() if(pConsole->m_Input.GetString()[0] != 0) { m_pConsole->PossibleCommands(pConsole->m_aCompletionBuffer, pConsole->m_CompletionFlagmask, PossibleCommandsRenderCallback, &Info); + pConsole->m_CompletionRenderOffset = Info.m_Offset; if(Info.m_EnumCount <= 0) { @@ -552,6 +572,41 @@ void CGameConsole::Toggle(int Type) m_ConsoleType = Type; } +void CGameConsole::Dump(int Type) +{ + CInstance *pConsole = Type == 1 ? &m_RemoteConsole : &m_LocalConsole; + char aFilename[128]; + time_t Time; + char aDate[20]; + + time(&Time); + tm* TimeInfo = localtime(&Time); + strftime(aDate, sizeof(aDate), "%Y-%m-%d_%I-%M", TimeInfo); + + for(int i = 0; i < 10; i++) + { + IOHANDLE io; + str_format(aFilename, sizeof(aFilename), "dumps/%s_dump%s-%05d.txt", Type==1?"remote_console":"local_console", aDate, i); + io = Storage()->OpenFile(aFilename, IOFLAG_WRITE); + if(io) + { + #if defined(CONF_FAMILY_WINDOWS) + static const char Newline[] = "\r\n"; + #else + static const char Newline[] = "\n"; + #endif + + for(char *pEntry = pConsole->m_Backlog.First(); pEntry; pEntry = pConsole->m_Backlog.Next(pEntry)) + { + io_write(io, pEntry, str_length(pEntry)); + io_write(io, Newline, sizeof(Newline)-1); + } + io_close(io); + break; + } + } +} + void CGameConsole::ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData) { ((CGameConsole *)pUserData)->Toggle(0); @@ -562,6 +617,26 @@ void CGameConsole::ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUse ((CGameConsole *)pUserData)->Toggle(1); } +void CGameConsole::ConClearLocalConsole(IConsole::IResult *pResult, void *pUserData) +{ + ((CGameConsole *)pUserData)->m_LocalConsole.ClearBacklog(); +} + +void CGameConsole::ConClearRemoteConsole(IConsole::IResult *pResult, void *pUserData) +{ + ((CGameConsole *)pUserData)->m_RemoteConsole.ClearBacklog(); +} + +void CGameConsole::ConDumpLocalConsole(IConsole::IResult *pResult, void *pUserData) +{ + ((CGameConsole *)pUserData)->Dump(0); +} + +void CGameConsole::ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserData) +{ + ((CGameConsole *)pUserData)->Dump(1); +} + void CGameConsole::ClientConsolePrintCallback(const char *pStr, void *pUserData) { ((CGameConsole *)pUserData)->m_LocalConsole.PrintLine(pStr); @@ -588,6 +663,10 @@ void CGameConsole::OnConsoleInit() Console()->Register("toggle_local_console", "", CFGFLAG_CLIENT, ConToggleLocalConsole, this, "Toggle local console"); Console()->Register("toggle_remote_console", "", CFGFLAG_CLIENT, ConToggleRemoteConsole, this, "Toggle remote console"); + Console()->Register("clear_local_console", "", CFGFLAG_CLIENT, ConClearLocalConsole, this, "Clear local console"); + Console()->Register("clear_remote_console", "", CFGFLAG_CLIENT, ConClearRemoteConsole, this, "Clear remote console"); + Console()->Register("dump_local_console", "", CFGFLAG_CLIENT, ConDumpLocalConsole, this, "Dump local console"); + Console()->Register("dump_remote_console", "", CFGFLAG_CLIENT, ConDumpRemoteConsole, this, "Dump remote console"); } /* diff --git a/src/game/client/components/console.h b/src/game/client/components/console.h index d146307f..a4d22790 100644 --- a/src/game/client/components/console.h +++ b/src/game/client/components/console.h @@ -24,12 +24,15 @@ class CGameConsole : public CComponent char m_aCompletionBuffer[128]; int m_CompletionChosen; int m_CompletionFlagmask; + float m_CompletionRenderOffset; IConsole::CCommandInfo *m_pCommand; CInstance(int t); void Init(CGameConsole *pGameConsole); + void ClearBacklog(); + void ExecuteLine(const char *pLine); void OnInput(IInput::CEvent Event); @@ -53,11 +56,16 @@ class CGameConsole : public CComponent float m_StateChangeDuration; void Toggle(int Type); + void Dump(int Type); static void PossibleCommandsRenderCallback(const char *pStr, void *pUser); static void ClientConsolePrintCallback(const char *pStr, void *pUserData); static void ConToggleLocalConsole(IConsole::IResult *pResult, void *pUserData); static void ConToggleRemoteConsole(IConsole::IResult *pResult, void *pUserData); + static void ConClearLocalConsole(IConsole::IResult *pResult, void *pUserData); + static void ConClearRemoteConsole(IConsole::IResult *pResult, void *pUserData); + static void ConDumpLocalConsole(IConsole::IResult *pResult, void *pUserData); + static void ConDumpRemoteConsole(IConsole::IResult *pResult, void *pUserData); public: CGameConsole(); diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index a3ae5a4d..73dfef53 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -71,57 +71,58 @@ void CHud::RenderScoreHud() // render small score hud if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) && (GameFlags&GAMEFLAG_TEAMS)) { + char aScoreTeam[2][32]; + str_format(aScoreTeam[0], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); + str_format(aScoreTeam[1], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue); + float aScoreTeamWidth[2] = {TextRender()->TextWidth(0, 14.0f, aScoreTeam[0], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[1], -1)}; + float ScoreWidthMax = max(max(aScoreTeamWidth[0], aScoreTeamWidth[1]), 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++) { + // draw box Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); if(t == 0) - Graphics()->SetColor(1,0,0,0.25f); + Graphics()->SetColor(1.0f, 0.0f, 0.0f, 0.25f); else - Graphics()->SetColor(0,0,1,0.25f); - RenderTools()->DrawRoundRect(Whole-45, 300-40-15+t*20, 50, 18, 5.0f); + 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(); - char Buf[32]; - str_format(Buf, sizeof(Buf), "%d", t?m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue : m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); - float w = TextRender()->TextWidth(0, 14, Buf, -1); - - if(GameFlags&GAMEFLAG_FLAGS) + // 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]) { - TextRender()->Text(0, Whole-20-w/2+5, 300-40-15+t*20, 14, Buf, -1); - if(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))) { - 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))) - { - Graphics()->BlendNormal(); - Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); - Graphics()->QuadsBegin(); - - if(t == 0) RenderTools()->SelectSprite(SPRITE_FLAG_RED); - else RenderTools()->SelectSprite(SPRITE_FLAG_BLUE); - - float Size = 16; - IGraphics::CQuadItem QuadItem(Whole-40+2, 300-40-15+t*20+1, Size/2, Size); - Graphics()->QuadsDrawTL(&QuadItem, 1); - Graphics()->QuadsEnd(); - } - else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0) - { - 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, pName, -1); - TextRender()->Text(0, Whole-40-7-w, 300-40-15+t*20+2, 10, pName, -1); - 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-40+5, 300-40-15+9+t*20+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 - TextRender()->Text(0, Whole-20-w/2, 300-40-15+t*20, 14, Buf, -1); } } } diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 70479e53..b29bee99 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -104,7 +104,7 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu { m_pClient->m_pEffects->PowerupShine(Pos, vec2(96,18)); Size *= 2.0f; - Pos.x += 10.0f; + Pos.x -= 10.0f; } } diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index 202ea2da..62b32a1f 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -42,7 +42,7 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void pChannels[2] = 0; pChannels[3] = 0; - CEnvPoint *pPoints; + CEnvPoint *pPoints = 0; { int Start, Num; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 229fce80..9ea9c6ef 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -165,7 +165,6 @@ class CMenus : public CComponent void DemolistPopulate(); static void DemolistCountCallback(const char *pName, int IsDir, void *pUser); static void DemolistFetchCallback(const char *pName, int IsDir, void *pUser); - static void IsDirCallback(const char *pName, int IsDir, void *pUser); void DemoSetParentDirectory(); // found in menus.cpp diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 9b816f15..32243a2a 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -309,7 +309,12 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) TextRender()->TextEx(&Cursor, pItem->m_aName, -1); } else if(Id == COL_MAP) - UI()->DoLabel(&Button, pItem->m_aMap, 12.0f, -1); + { + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Button.w; + TextRender()->TextEx(&Cursor, pItem->m_aMap, -1); + } else if(Id == COL_PLAYERS) { str_format(aTemp, sizeof(aTemp), "%i/%i", pItem->m_NumPlayers, pItem->m_MaxPlayers); @@ -332,7 +337,10 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) } else if(Id == COL_GAMETYPE) { - UI()->DoLabel(&Button, pItem->m_aGameType, 12.0f, 0); + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, Button.x, Button.y, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = Button.w; + TextRender()->TextEx(&Cursor, pItem->m_aGameType, -1); } } diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index ec1ead8e..f8cf8e4f 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -1,5 +1,4 @@ -#include <string.h> #include <base/math.h> @@ -380,9 +379,9 @@ struct FETCH_CALLBACKINFO void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser) { - if(IsDir || pName[0] == '.') + if(pName[0] == '.') return; - + FETCH_CALLBACKINFO *pInfo = (FETCH_CALLBACKINFO *)pUser; CDemoItem Item; @@ -391,17 +390,12 @@ void CMenus::DemolistFetchCallback(const char *pName, int IsDir, void *pUser) pInfo->m_pSelf->m_lDemos.add(Item); } -void CMenus::IsDirCallback(const char *pName, int IsDir, void *pUser) -{ - *((bool *)pUser) = true; -} - void CMenus::DemolistPopulate() { m_lDemos.clear(); - if(strncmp(m_aCurrentDemoFolder, "demos", 256)) //add parent folder + if(str_comp_num(m_aCurrentDemoFolder, "demos", 256)) //add parent folder { CDemoItem Item; str_copy(Item.m_aName, "..", sizeof(Item.m_aName)); @@ -413,7 +407,7 @@ void CMenus::DemolistPopulate() char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s/%s", Client()->UserDirectory(), m_aCurrentDemoFolder); - FETCH_CALLBACKINFO Info = {this, aBuf, 0}; + FETCH_CALLBACKINFO Info = {this, aBuf, m_aCurrentDemoFolder[6]}; //skip "demos/" fs_listdir(aBuf, DemolistFetchCallback, &Info); Info.m_pPrefix = m_aCurrentDemoFolder; fs_listdir(m_aCurrentDemoFolder, DemolistFetchCallback, &Info); @@ -457,10 +451,10 @@ void CMenus::RenderDemoList(CUIRect MainView) bool IsDir = false; - if(!strncmp(m_lDemos[s_SelectedItem].m_aName, "..", 256)) //parent folder + if(!str_comp_num(m_lDemos[s_SelectedItem].m_aName, "..", 256)) //parent folder + IsDir = true; + else if(fs_is_dir(m_lDemos[s_SelectedItem].m_aFilename)) IsDir = true; - else - fs_listdir(m_lDemos[s_SelectedItem].m_aFilename, IsDirCallback, &IsDir); static int s_RefreshButton = 0; @@ -470,17 +464,17 @@ void CMenus::RenderDemoList(CUIRect MainView) } static int s_PlayButton = 0; - char aTitleButton[8]; + char aTitleButton[10]; if(IsDir) - str_copy(aTitleButton, "Open", sizeof(aTitleButton)); + str_copy(aTitleButton, Localize("Open"), sizeof(aTitleButton)); else - str_copy(aTitleButton, "Play", sizeof(aTitleButton)); - // /!\ TODO: Add "Open" in Localization /!\ - if(DoButton_Menu(&s_PlayButton, Localize(aTitleButton), 0, &PlayRect) || Activated) + str_copy(aTitleButton, Localize("Play"), sizeof(aTitleButton)); + + if(DoButton_Menu(&s_PlayButton, aTitleButton, 0, &PlayRect) || Activated) { if(s_SelectedItem >= 0 && s_SelectedItem < m_lDemos.size()) { - if(!strncmp(m_lDemos[s_SelectedItem].m_aName, "..", 256)) + if(!str_comp_num(m_lDemos[s_SelectedItem].m_aName, "..", 256)) { DemoSetParentDirectory(); DemolistPopulate(); @@ -496,7 +490,7 @@ void CMenus::RenderDemoList(CUIRect MainView) { const char *pError = Client()->DemoPlayer_Play(m_lDemos[s_SelectedItem].m_aFilename); if(pError) - PopupMessage(Localize("Error"), pError, Localize("Ok")); + PopupMessage(Localize("Error"), Localize(pError), Localize("Ok")); } } } @@ -519,6 +513,6 @@ void CMenus::DemoSetParentDirectory() for(i = 0; i < 256; i++) { if(i >= Stop) - m_aCurrentDemoFolder[i] = NULL; + m_aCurrentDemoFolder[i] = 0; } } diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 8ad7b0cb..ad7b3bcd 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -319,7 +319,7 @@ void CPlayers::RenderPlayer( bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0); // evaluate animation - float WalkTime = fmod(Position.x, 100.0f)/100.0f; + float WalkTime = fmod(absolute(Position.x), 100.0f)/100.0f; CAnimState State; State.Set(&g_pData->m_aAnimations[ANIM_BASE], 0); diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp index 63963dc2..da97ed61 100644 --- a/src/game/editor/ed_editor.cpp +++ b/src/game/editor/ed_editor.cpp @@ -573,7 +573,21 @@ static void CallbackAppendMap(const char *pFileName, void *pUser) else pEditor->SortImages(); } -static void CallbackSaveMap(const char *pFileName, void *pUser){ if(((CEditor*)pUser)->Save(pFileName)) str_copy(((CEditor*)pUser)->m_aFileName, pFileName, 512); } +static void CallbackSaveMap(const char *pFileName, void *pUser) +{ + char aBuf[1024]; + const int Length = str_length(pFileName); + // add map extension + if(Length <= 4 || pFileName[Length-4] != '.' || str_comp_nocase(pFileName+Length-3, "map")) + { + str_format(aBuf, sizeof(aBuf), "%s.map", pFileName); + pFileName = aBuf; + } + + CEditor *pEditor = static_cast<CEditor*>(pUser); + if(pEditor->Save(pFileName)) + str_copy(pEditor->m_aFileName, pFileName, sizeof(pEditor->m_aFileName)); +} void CEditor::DoToolbar(CUIRect ToolBar) { @@ -593,7 +607,7 @@ void CEditor::DoToolbar(CUIRect ToolBar) if(Input()->KeyDown('s') && (Input()->KeyPressed(KEY_LCTRL) || Input()->KeyPressed(KEY_RCTRL))) { if(m_aFileName[0]) - Save(m_aFileName); + CallbackSaveMap(m_aFileName, this); else InvokeFileDialog(IStorage::TYPE_SAVE, Localize("Save map"), Localize("Save"), "maps/", "", CallbackSaveMap, this); } @@ -773,6 +787,17 @@ void CEditor::DoToolbar(CUIRect ToolBar) DoMapBorder(); } } + + TB_Bottom.VSplitLeft(5.0f, 0, &TB_Bottom); + + // refocus button + TB_Bottom.VSplitLeft(50.0f, &Button, &TB_Bottom); + static int s_RefocusButton = 0; + if(DoButton_Editor(&s_RefocusButton, Localize("Refocus"), m_WorldOffsetX&&m_WorldOffsetY?0:-1, &Button, 0, Localize("[HOME] Restore map focus")) || Input()->KeyDown(KEY_HOME)) + { + m_WorldOffsetX = 0; + m_WorldOffsetY = 0; + } } static void Rotate(CPoint *pCenter, CPoint *pPoint, float Rotation) @@ -1317,24 +1342,26 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) } CLayerGroup *g = GetSelectedGroup(); - m_Brush.m_OffsetX += g->m_OffsetX; - m_Brush.m_OffsetY += g->m_OffsetY; - m_Brush.m_ParallaxX = g->m_ParallaxX; - m_Brush.m_ParallaxY = g->m_ParallaxY; - m_Brush.Render(); - float w, h; - m_Brush.GetSize(&w, &h); - - IGraphics::CLineItem Array[4] = { - IGraphics::CLineItem(0, 0, w, 0), - IGraphics::CLineItem(w, 0, w, h), - IGraphics::CLineItem(w, h, 0, h), - IGraphics::CLineItem(0, h, 0, 0)}; - Graphics()->TextureSet(-1); - Graphics()->LinesBegin(); - Graphics()->LinesDraw(Array, 4); - Graphics()->LinesEnd(); - + if(g) + { + m_Brush.m_OffsetX += g->m_OffsetX; + m_Brush.m_OffsetY += g->m_OffsetY; + m_Brush.m_ParallaxX = g->m_ParallaxX; + m_Brush.m_ParallaxY = g->m_ParallaxY; + m_Brush.Render(); + float w, h; + m_Brush.GetSize(&w, &h); + + IGraphics::CLineItem Array[4] = { + IGraphics::CLineItem(0, 0, w, 0), + IGraphics::CLineItem(w, 0, w, h), + IGraphics::CLineItem(w, h, 0, h), + IGraphics::CLineItem(0, h, 0, 0)}; + Graphics()->TextureSet(-1); + Graphics()->LinesBegin(); + Graphics()->LinesDraw(Array, 4); + Graphics()->LinesEnd(); + } } } } @@ -1393,6 +1420,15 @@ void CEditor::DoMapEditor(CUIRect View, CUIRect ToolBar) } } } + else if(UI()->ActiveItem() == s_pEditorId) + { + // release mouse + if(!UI()->MouseButton(0)) + { + s_Operation = OP_NONE; + UI()->SetActiveItem(0); + } + } if(GetSelectedGroup() && GetSelectedGroup()->m_UseClipping) { @@ -1655,19 +1691,6 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) LayersBox.VSplitRight(3.0f, &LayersBox, 0); // extra spacing Scroll.HMargin(5.0f, &Scroll); s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); - - if(ScrollNum > 0) - { - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) - s_ScrollValue -= 3.0f/ScrollNum; - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) - s_ScrollValue += 3.0f/ScrollNum; - - if(s_ScrollValue < 0) s_ScrollValue = 0; - if(s_ScrollValue > 1) s_ScrollValue = 1; - } - else - ScrollNum = 0; } int LayerStartAt = (int)(ScrollNum*s_ScrollValue); @@ -1953,19 +1976,6 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect ToolBar, CUIRect View) ToolBox.VSplitRight(3.0f, &ToolBox, 0); // extra spacing Scroll.HMargin(5.0f, &Scroll); s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); - - if(ScrollNum > 0) - { - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_UP)) - s_ScrollValue -= 3.0f/ScrollNum; - if(Input()->KeyPresses(KEY_MOUSE_WHEEL_DOWN)) - s_ScrollValue += 3.0f/ScrollNum; - - if(s_ScrollValue < 0) s_ScrollValue = 0; - if(s_ScrollValue > 1) s_ScrollValue = 1; - } - else - ScrollNum = 0; } int ImageStartAt = (int)(ScrollNum*s_ScrollValue); @@ -2670,7 +2680,7 @@ int CEditor::PopupMenuFile(CEditor *pEditor, CUIRect View) if(pEditor->DoButton_MenuItem(&s_SaveButton, Localize("Save"), 0, &Slot, 0, Localize("Saves the current map"))) { if(pEditor->m_aFileName[0]) - pEditor->Save(pEditor->m_aFileName); + CallbackSaveMap(pEditor->m_aFileName, pEditor); else pEditor->InvokeFileDialog(IStorage::TYPE_SAVE, Localize("Save Map"), Localize("Save"), "maps/", "", CallbackSaveMap, pEditor); return 1; @@ -2865,6 +2875,19 @@ void CEditor::Reset(bool CreateDefault) m_SelectedPoints = 0; m_SelectedEnvelope = 0; m_SelectedImage = 0; + + m_WorldOffsetX = 0; + m_WorldOffsetY = 0; + m_EditorOffsetX = 0.0f; + m_EditorOffsetY = 0.0f; + + m_WorldZoom = 1.0f; + m_ZoomLevel = 200; + + m_MouseDeltaX = 0; + m_MouseDeltaY = 0; + m_MouseDeltaWx = 0; + m_MouseDeltaWy = 0; } void CEditorMap::MakeGameLayer(CLayer *pLayer) @@ -2895,6 +2918,28 @@ void CEditorMap::Clean() void CEditorMap::CreateDefault(int EntitiesTexture) { + // add background + CLayerGroup *pGroup = NewGroup(); + pGroup->m_ParallaxX = 0; + pGroup->m_ParallaxY = 0; + CLayerQuads *pLayer = new CLayerQuads; + pLayer->m_pEditor = m_pEditor; + CQuad *pQuad = pLayer->NewQuad(); + const int Width = 800000; + const int Height = 600000; + pQuad->m_aPoints[0].x = pQuad->m_aPoints[2].x = -Width; + pQuad->m_aPoints[1].x = pQuad->m_aPoints[3].x = Width; + pQuad->m_aPoints[0].y = pQuad->m_aPoints[1].y = -Height; + pQuad->m_aPoints[2].y = pQuad->m_aPoints[3].y = Height; + pQuad->m_aColors[0].r = pQuad->m_aColors[1].r = 94; + pQuad->m_aColors[0].g = pQuad->m_aColors[1].g = 132; + pQuad->m_aColors[0].b = pQuad->m_aColors[1].b = 174; + pQuad->m_aColors[2].r = pQuad->m_aColors[3].r = 204; + pQuad->m_aColors[2].g = pQuad->m_aColors[3].g = 232; + pQuad->m_aColors[2].b = pQuad->m_aColors[3].b = 255; + pGroup->AddLayer(pLayer); + + // add game layer MakeGameGroup(NewGroup()); MakeGameLayer(new CLayerGame(50, 50)); m_pGameGroup->AddLayer(m_pGameLayer); @@ -2938,7 +2983,7 @@ void CEditor::DoMapBorder() pT->m_pTiles[i].m_Index = 1; } - for(int i = ((pT->m_Width-2)*pT->m_Height); i < pT->m_Width*pT->m_Height; ++i) + for(int i = (pT->m_Width*(pT->m_Height-2)); i < pT->m_Width*pT->m_Height; ++i) pT->m_pTiles[i].m_Index = 1; } diff --git a/src/game/editor/ed_popups.cpp b/src/game/editor/ed_popups.cpp index 5e833ba6..001a7249 100644 --- a/src/game/editor/ed_popups.cpp +++ b/src/game/editor/ed_popups.cpp @@ -20,6 +20,10 @@ static int g_UiNumPopups = 0; void CEditor::UiInvokePopupMenu(void *Id, int Flags, float x, float y, float w, float h, int (*pfnFunc)(CEditor *pEditor, CUIRect Rect), void *pExtra) { dbg_msg("", "invoked"); + if(x + w > UI()->Screen()->w) + x -= w; + if(y + h > UI()->Screen()->h) + y -= h; s_UiPopups[g_UiNumPopups].m_pId = Id; s_UiPopups[g_UiNumPopups].m_IsMenu = Flags; s_UiPopups[g_UiNumPopups].m_Rect.x = x; @@ -84,6 +88,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View) pEditor->DoButton_Editor(&s_DeleteButton, Localize("Delete group"), 0, &Button, 0, Localize("Delete group"))) { pEditor->m_Map.DeleteGroup(pEditor->m_SelectedGroup); + pEditor->m_SelectedGroup = max(0, pEditor->m_SelectedGroup-1); return 1; } diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 77d8f462..81d1f85b 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -585,14 +585,26 @@ void CCharacter::TickDefered() if(!StuckBefore && (StuckAfterMove || StuckAfterQuant)) { + // Hackish solution to get rid of strict-aliasing warning + union + { + float f; + unsigned u; + }StartPosX, StartPosY, StartVelX, StartVelY; + + StartPosX.f = StartPos.x; + StartPosY.f = StartPos.y; + StartVelX.f = StartVel.x; + StartVelY.f = StartVel.y; + dbg_msg("char_core", "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", StuckBefore, StuckAfterMove, StuckAfterQuant, StartPos.x, StartPos.y, StartVel.x, StartVel.y, - *((unsigned *)&StartPos.x), *((unsigned *)&StartPos.y), - *((unsigned *)&StartVel.x), *((unsigned *)&StartVel.y)); + StartPosX.u, StartPosY.u, + StartVelX.u, StartVelY.u); } int Events = m_Core.m_TriggeredEvents; diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 5b7051d3..07f8bf86 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -286,6 +286,7 @@ void IGameController::PostReset() GameServer()->m_apPlayers[i]->Respawn(); GameServer()->m_apPlayers[i]->m_Score = 0; GameServer()->m_apPlayers[i]->m_ScoreStartTick = Server()->Tick(); + GameServer()->m_apPlayers[i]->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2; } } } @@ -540,7 +541,7 @@ int IGameController::GetAutoTeam(int Notthisid) bool IGameController::CanJoinTeam(int Team, int Notthisid) { - if(Team == -1) + if(Team == -1 || (GameServer()->m_apPlayers[Notthisid] && GameServer()->m_apPlayers[Notthisid]->GetTeam() != -1)) return true; int aNumplayers[2] = {0,0}; |