From 0ce70f863b6e9a60e63e1f75a6d54b0efba2a44e Mon Sep 17 00:00:00 2001 From: marmare314 <49279081+Marmare314@users.noreply.github.com> Date: Fri, 17 Mar 2023 18:37:55 +0100 Subject: [PATCH] add proof mode for menu backgrounds closes #3009 --- .../client/components/menu_background.cpp | 53 ++++--- src/game/client/components/menu_background.h | 4 +- src/game/editor/editor.cpp | 132 ++++++++++++++++-- src/game/editor/editor.h | 7 + 4 files changed, 165 insertions(+), 31 deletions(-) diff --git a/src/game/client/components/menu_background.cpp b/src/game/client/components/menu_background.cpp index d23e71fe3..622e1cdc1 100644 --- a/src/game/client/components/menu_background.cpp +++ b/src/game/client/components/menu_background.cpp @@ -19,6 +19,36 @@ using namespace std::chrono_literals; +std::vector GenerateMenuBackgroundPositions() +{ + std::vector Positions(CMenuBackground::NUM_POS); + + Positions[CMenuBackground::POS_START] = vec2(500.0f, 500.0f); + Positions[CMenuBackground::POS_BROWSER_INTERNET] = vec2(1000.0f, 1000.0f); + Positions[CMenuBackground::POS_BROWSER_LAN] = vec2(1100.0f, 1000.0f); + Positions[CMenuBackground::POS_DEMOS] = vec2(900.0f, 100.0f); + Positions[CMenuBackground::POS_NEWS] = vec2(500.0f, 750.0f); + Positions[CMenuBackground::POS_BROWSER_FAVORITES] = vec2(1250.0f, 500.0f); + Positions[CMenuBackground::POS_SETTINGS_LANGUAGE] = vec2(500.0f, 1200.0f); + Positions[CMenuBackground::POS_SETTINGS_GENERAL] = vec2(500.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_PLAYER] = vec2(600.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_TEE] = vec2(700.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_APPEARANCE] = vec2(200.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_CONTROLS] = vec2(800.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_GRAPHICS] = vec2(900.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_SOUND] = vec2(1000.0f, 1000.0f); + Positions[CMenuBackground::POS_SETTINGS_DDNET] = vec2(1200.0f, 200.0f); + Positions[CMenuBackground::POS_SETTINGS_ASSETS] = vec2(500.0f, 500.0f); + for(int i = 0; i < CMenuBackground::POS_BROWSER_CUSTOM_NUM; ++i) + Positions[CMenuBackground::POS_BROWSER_CUSTOM0 + i] = vec2(500.0f + (75.0f * (float)i), 650.0f - (75.0f * (float)i)); + for(int i = 0; i < CMenuBackground::POS_SETTINGS_RESERVED_NUM; ++i) + Positions[CMenuBackground::POS_SETTINGS_RESERVED0 + i] = vec2(0, 0); + for(int i = 0; i < CMenuBackground::POS_RESERVED_NUM; ++i) + Positions[CMenuBackground::POS_RESERVED0 + i] = vec2(0, 0); + + return Positions; +} + CMenuBackground::CMenuBackground() : CBackground(CMapLayers::TYPE_FULL_DESIGN, false) { @@ -56,28 +86,7 @@ void CMenuBackground::OnInit() void CMenuBackground::ResetPositions() { - m_aPositions[POS_START] = vec2(500.0f, 500.0f); - m_aPositions[POS_BROWSER_INTERNET] = vec2(1000.0f, 1000.0f); - m_aPositions[POS_BROWSER_LAN] = vec2(1100.0f, 1000.0f); - m_aPositions[POS_DEMOS] = vec2(900.0f, 100.0f); - m_aPositions[POS_NEWS] = vec2(500.0f, 750.0f); - m_aPositions[POS_BROWSER_FAVORITES] = vec2(1250.0f, 500.0f); - m_aPositions[POS_SETTINGS_LANGUAGE] = vec2(500.0f, 1200.0f); - m_aPositions[POS_SETTINGS_GENERAL] = vec2(500.0f, 1000.0f); - m_aPositions[POS_SETTINGS_PLAYER] = vec2(600.0f, 1000.0f); - m_aPositions[POS_SETTINGS_TEE] = vec2(700.0f, 1000.0f); - m_aPositions[POS_SETTINGS_APPEARANCE] = vec2(200.0f, 1000.0f); - m_aPositions[POS_SETTINGS_CONTROLS] = vec2(800.0f, 1000.0f); - m_aPositions[POS_SETTINGS_GRAPHICS] = vec2(900.0f, 1000.0f); - m_aPositions[POS_SETTINGS_SOUND] = vec2(1000.0f, 1000.0f); - m_aPositions[POS_SETTINGS_DDNET] = vec2(1200.0f, 200.0f); - m_aPositions[POS_SETTINGS_ASSETS] = vec2(500.0f, 500.0f); - for(int i = 0; i < POS_BROWSER_CUSTOM_NUM; ++i) - m_aPositions[POS_BROWSER_CUSTOM0 + i] = vec2(500.0f + (75.0f * (float)i), 650.0f - (75.0f * (float)i)); - for(int i = 0; i < POS_SETTINGS_RESERVED_NUM; ++i) - m_aPositions[POS_SETTINGS_RESERVED0 + i] = vec2(0, 0); - for(int i = 0; i < POS_RESERVED_NUM; ++i) - m_aPositions[POS_RESERVED0 + i] = vec2(0, 0); + m_aPositions = GenerateMenuBackgroundPositions(); } int CMenuBackground::ThemeScan(const char *pName, int IsDir, int DirType, void *pUser) diff --git a/src/game/client/components/menu_background.h b/src/game/client/components/menu_background.h index 775a94b0e..ad64a15d4 100644 --- a/src/game/client/components/menu_background.h +++ b/src/game/client/components/menu_background.h @@ -28,6 +28,8 @@ public: bool operator<(const CTheme &Other) const { return m_Name < Other.m_Name; } }; +std::vector GenerateMenuBackgroundPositions(); + class CMenuBackground : public CBackground { std::chrono::nanoseconds m_ThemeScanStartTime{0}; @@ -83,7 +85,7 @@ public: vec2 m_MenuCenter; vec2 m_RotationCenter; - vec2 m_aPositions[NUM_POS]; + std::vector m_aPositions; int m_CurrentPosition; vec2 m_AnimationStartPos; bool m_ChangedPosition; diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 7fda2ed0d..b801fccfc 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -919,7 +920,17 @@ void CEditor::DoToolbar(CUIRect ToolBar) if(DoButton_Editor(&s_ProofButton, "Proof", m_ProofBorders, &Button, 0, "[ctrl+p] Toggles proof borders. These borders represent what a player maximum can see.") || (m_Dialog == DIALOG_NONE && m_EditBoxActive == 0 && Input()->KeyPress(KEY_P) && ModPressed)) { - m_ProofBorders = !m_ProofBorders; + m_ProofBorders = !m_ProofBorders && !m_MenuProofBorders; + } + + TB_Top.VSplitLeft(5.0f, nullptr, &TB_Top); + + // menu proof button + TB_Top.VSplitLeft(60.0f, &Button, &TB_Top); + static int s_MenuProofButton = 0; + if(DoButton_Editor(&s_MenuProofButton, "Proof Menu", m_MenuProofBorders, &Button, 0, "Toggles menu proof borders. These borders represent what will be shown in the menu.")) + { + m_MenuProofBorders = !m_MenuProofBorders && !m_ProofBorders; } TB_Top.VSplitLeft(5.0f, nullptr, &TB_Top); @@ -1131,10 +1142,33 @@ void CEditor::DoToolbar(CUIRect ToolBar) { TB_Bottom.VSplitLeft(45.0f, &Button, &TB_Bottom); static int s_RefocusButton = 0; - if(DoButton_Editor(&s_RefocusButton, "Refocus", m_WorldOffsetX && m_WorldOffsetY ? 0 : -1, &Button, 0, "[HOME] Restore map focus") || (m_Dialog == DIALOG_NONE && m_EditBoxActive == 0 && Input()->KeyPress(KEY_HOME))) + int FocusButtonChecked; + if(m_MenuProofBorders) { - m_WorldOffsetX = 0; - m_WorldOffsetY = 0; + if(distance(m_vMenuBackgroundPositions[m_CurrentMenuProofIndex], vec2(m_WorldOffsetX, m_WorldOffsetY)) < 0.0001f) + FocusButtonChecked = -1; + else + FocusButtonChecked = 1; + } + else + { + if(m_WorldOffsetX == 0 && m_WorldOffsetY == 0) + FocusButtonChecked = -1; + else + FocusButtonChecked = 1; + } + if(DoButton_Editor(&s_RefocusButton, "Refocus", FocusButtonChecked, &Button, 0, "[HOME] Restore map focus") || (m_Dialog == DIALOG_NONE && m_EditBoxActive == 0 && Input()->KeyPress(KEY_HOME))) + { + if(m_MenuProofBorders) + { + m_WorldOffsetX = m_vMenuBackgroundPositions[m_CurrentMenuProofIndex].x; + m_WorldOffsetY = m_vMenuBackgroundPositions[m_CurrentMenuProofIndex].y; + } + else + { + m_WorldOffsetX = 0; + m_WorldOffsetY = 0; + } } TB_Bottom.VSplitLeft(5.0f, nullptr, &TB_Bottom); } @@ -2790,6 +2824,44 @@ void CEditor::DoMapEditor(CUIRect View) } } + // menu proof selection + if(m_MenuProofBorders && !m_ShowPicker) + { + for(int i = 0; i < (int)m_vMenuBackgroundPositions.size(); i++) + { + vec2 Pos = m_vMenuBackgroundPositions[i]; + if(i == m_CurrentMenuProofIndex || Pos == vec2(0, 0)) + continue; + + Pos += vec2(m_WorldOffsetX, m_WorldOffsetY) - m_vMenuBackgroundPositions[m_CurrentMenuProofIndex]; + Pos.y -= 3.0f; + + vec2 MousePos(m_MouseWorldNoParaX, m_MouseWorldNoParaY); + if(distance(Pos, MousePos) <= 20.0f) + { + UI()->SetHotItem(&m_vMenuBackgroundPositions[i]); + + if(UI()->CheckActiveItem(&m_vMenuBackgroundPositions[i])) + { + if(!UI()->MouseButton(0)) + { + m_CurrentMenuProofIndex = i; + m_WorldOffsetX = m_vMenuBackgroundPositions[i].x; + m_WorldOffsetY = m_vMenuBackgroundPositions[i].y; + UI()->SetActiveItem(nullptr); + } + } + else if(UI()->HotItem() == &m_vMenuBackgroundPositions[i]) + { + m_pTooltip = "Switch proof position"; + + if(UI()->MouseButton(0)) + UI()->SetActiveItem(&m_vMenuBackgroundPositions[i]); + } + } + } + } + // do panning if(UI()->CheckActiveItem(s_pEditorID)) { @@ -2860,7 +2932,7 @@ void CEditor::DoMapEditor(CUIRect View) } // render screen sizes - if(m_ProofBorders && !m_ShowPicker) + if((m_ProofBorders || m_MenuProofBorders) && !m_ShowPicker) { CLayerGroup *pGameGroup = m_Map.m_pGameGroup; pGameGroup->MapScreen(); @@ -2878,9 +2950,10 @@ void CEditor::DoMapEditor(CUIRect View) float aPoints[4]; float Aspect = Start + (End - Start) * (i / (float)NumSteps); + float Zoom = m_MenuProofBorders ? 0.7f : 1.0f; RenderTools()->MapScreenToWorld( m_WorldOffsetX, m_WorldOffsetY, - 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); + 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, Zoom, aPoints); if(i == 0) { @@ -2920,9 +2993,10 @@ void CEditor::DoMapEditor(CUIRect View) const float aAspects[] = {4.0f / 3.0f, 16.0f / 10.0f, 5.0f / 4.0f, 16.0f / 9.0f}; float Aspect = aAspects[i]; + float Zoom = m_MenuProofBorders ? 0.7f : 1.0f; RenderTools()->MapScreenToWorld( m_WorldOffsetX, m_WorldOffsetY, - 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, 1.0f, aPoints); + 100.0f, 100.0f, 100.0f, 0.0f, 0.0f, Aspect, Zoom, aPoints); CUIRect r; r.x = aPoints[0]; @@ -2941,12 +3015,29 @@ void CEditor::DoMapEditor(CUIRect View) } Graphics()->LinesEnd(); - // tee position (blue circle) + // tee position (blue circle) and other screen positions { Graphics()->TextureClear(); Graphics()->QuadsBegin(); Graphics()->SetColor(0, 0, 1, 0.3f); Graphics()->DrawCircle(m_WorldOffsetX, m_WorldOffsetY - 3.0f, 20.0f, 32); + + if(m_MenuProofBorders) + { + Graphics()->SetColor(0, 1, 0, 0.3f); + + for(int i = 0; i < (int)m_vMenuBackgroundPositions.size(); i++) + { + vec2 Pos = m_vMenuBackgroundPositions[i]; + if(i == m_CurrentMenuProofIndex || Pos == vec2(0, 0)) + continue; + + Pos += vec2(m_WorldOffsetX, m_WorldOffsetY) - m_vMenuBackgroundPositions[m_CurrentMenuProofIndex]; + + Graphics()->DrawCircle(Pos.x, Pos.y - 3.0f, 20.0f, 32); + } + } + Graphics()->QuadsEnd(); } } @@ -6819,6 +6910,16 @@ void CEditor::Init() m_Map.m_Modified = false; ms_PickerColor = ColorHSVA(1.0f, 0.0f, 0.0f); + + m_vMenuBackgroundPositions = GenerateMenuBackgroundPositions(); + for(size_t i = 0; i < m_vMenuBackgroundPositions.size(); i++) + { + for(size_t j = 0; j < m_vMenuBackgroundPositions.size(); j++) + { + if(i != j && distance(m_vMenuBackgroundPositions[i], m_vMenuBackgroundPositions[j]) < 0.001f) + m_vMenuBackgroundPositions[j] = vec2(0, 0); + } + } } void CEditor::PlaceBorderTiles() @@ -6897,6 +6998,21 @@ void CEditor::OnUpdate() m_MouseWorldX = 0.0f; m_MouseWorldY = 0.0f; } + + for(CLayerGroup *pGameGroup : m_Map.m_vpGroups) + { + if(!pGameGroup->m_GameGroup) + continue; + + float aPoints[4]; + pGameGroup->Mapping(aPoints); + + float WorldWidth = aPoints[2] - aPoints[0]; + float WorldHeight = aPoints[3] - aPoints[1]; + + m_MouseWorldNoParaX = aPoints[0] + WorldWidth * (s_MouseX / Graphics()->WindowWidth()); + m_MouseWorldNoParaY = aPoints[1] + WorldHeight * (s_MouseY / Graphics()->WindowHeight()); + } } } diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index ff0a2c6a5..0390a763e 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -830,6 +830,8 @@ public: m_GuiActive = true; m_ProofBorders = false; + m_MenuProofBorders = false; + m_CurrentMenuProofIndex = 0; m_PreviewZoom = false; m_ShowTileInfo = false; @@ -1068,12 +1070,17 @@ public: bool m_ShowMousePointer; bool m_GuiActive; bool m_ProofBorders; + bool m_MenuProofBorders; + int m_CurrentMenuProofIndex; + std::vector m_vMenuBackgroundPositions; bool m_PreviewZoom; float m_MouseWScale = 1.0f; // Mouse (i.e. UI) scale relative to the World (selected Group) float m_MouseX = 0.0f; float m_MouseY = 0.0f; float m_MouseWorldX = 0.0f; float m_MouseWorldY = 0.0f; + float m_MouseWorldNoParaX = 0.0f; + float m_MouseWorldNoParaY = 0.0f; float m_MouseDeltaX; float m_MouseDeltaY; float m_MouseDeltaWx;