From f1ad42c4e5685136e44b6ab7478c1923997b05da Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 Jun 2017 22:30:40 +0200 Subject: [PATCH] - instead of discarding protected menu replacements, try to merge them with the original version. Testing with Adventures of Square this mostly works, but it is clear that a list of old and deleted CVARs still needs to be added so that any items referring to those can be eliminated as well. Some stuff is still slipping through that refers to features which no longer exist. --- src/menu/menu.cpp | 2 +- src/menu/menu.h | 7 ++-- src/menu/menudef.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++-- src/namedef.h | 11 +++++++ 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 4ea76fe653..8893b57698 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -1121,7 +1121,7 @@ DEFINE_FIELD(FOptionMenuSettings, mLinespacing) struct IJoystickConfig; // These functions are used by dynamic menu creation. -DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v) +DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, int v) { auto c = PClass::FindClass("OptionMenuItemStaticText"); auto p = c->CreateNew(); diff --git a/src/menu/menu.h b/src/menu/menu.h index d5dd0d5c4a..d5211421ff 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -109,6 +109,7 @@ extern FSavegameManager savegameManager; class DMenu; extern DMenu *CurrentMenu; extern int MenuTime; +class DMenuItemBase; //============================================================================= // @@ -125,18 +126,17 @@ public: FString mNetgameMessage; PClass *mClass = nullptr; bool mProtected = false; + TArray mItems; virtual size_t PropagateMark() { return 0; } }; -class DMenuItemBase; class DListMenuDescriptor : public DMenuDescriptor { DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor) public: - TArray mItems; int mSelectedItem; double mSelectOfsX; double mSelectOfsY; @@ -187,7 +187,6 @@ class DOptionMenuDescriptor : public DMenuDescriptor DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor) public: - TArray mItems; FString mTitle; int mSelectedItem; int mDrawTop; @@ -350,7 +349,7 @@ void M_MarkMenus(); struct IJoystickConfig; -DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, bool v); +DMenuItemBase * CreateOptionMenuItemStaticText(const char *name, int v = -1); DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center); DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings); DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 504fd97853..e3184d3168 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -516,6 +516,52 @@ static bool CheckCompatible(DMenuDescriptor *newd, DMenuDescriptor *oldd) return newd->mClass->IsDescendantOf(oldd->mClass); } +static int GetGroup(DMenuItemBase *desc) +{ + if (desc->IsKindOf(NAME_OptionMenuItemCommand)) return 2; + if (desc->IsKindOf(NAME_OptionMenuItemSubmenu)) return 1; + if (desc->IsKindOf(NAME_OptionMenuItemControlBase)) return 3; + if (desc->IsKindOf(NAME_OptionMenuItemOptionBase)) return 4; + if (desc->IsKindOf(NAME_OptionMenuSliderBase)) return 4; + if (desc->IsKindOf(NAME_OptionMenuFieldBase)) return 4; + if (desc->IsKindOf(NAME_OptionMenuItemColorPicker)) return 4; + if (desc->IsKindOf(NAME_OptionMenuItemStaticText)) return 5; + if (desc->IsKindOf(NAME_OptionMenuItemStaticTextSwitchable)) return 5; + return 0; +} + +static bool FindMatchingItem(DMenuItemBase *desc) +{ + int grp = GetGroup(desc); + if (grp == 0) return false; // no idea what this is. + if (grp == 5) return true; // static texts always match + + FName name = desc->mAction; + if (grp == 1) + { + // Check for presence of menu + auto menu = MenuDescriptors.CheckKey(name); + if (menu == nullptr) return true; + } + else if (grp == 4) + { + // Check for presence of CVAR and blacklist + auto cv = GetCVar(nullptr, name.GetChars()); + if (cv == nullptr) return true; + } + + MenuDescriptorList::Iterator it(MenuDescriptors); + MenuDescriptorList::Pair *pair; + while (it.NextPair(pair)) + { + for (auto it : pair->Value->mItems) + { + if (it->mAction == name && GetGroup(it) == grp) return true; + } + } + return false; +} + static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc) { DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName); @@ -523,7 +569,32 @@ static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc) { if ((*pOld)->mProtected) { - sc.ScriptMessage("Cannot replace protected menu %s!", desc->mMenuName.GetChars()); + // If this tries to replace an option menu with an option menu, let's append all new entries to the old menu. + // Otherwise bail out because for list menus it's not that simple. + if (desc->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)) || (*pOld)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor))) + { + sc.ScriptMessage("Cannot replace protected menu %s.", desc->mMenuName.GetChars()); + return true; + } + for (int i = desc->mItems.Size()-1; i >= 0; i--) + { + if (FindMatchingItem(desc->mItems[i])) + { + desc->mItems.Delete(i); + } + } + if (desc->mItems.Size() > 0) + { + auto sep = CreateOptionMenuItemStaticText("---------------", CR_YELLOW); + (*pOld)->mItems.Push(sep); + for (auto it : desc->mItems) + { + (*pOld)->mItems.Push(it); + } + desc->mItems.Clear(); + + sc.ScriptMessage("Merged %d items into %s", desc->mItems.Size(), desc->mMenuName.GetChars()); + } return true; } @@ -1400,9 +1471,9 @@ static void InitKeySections() for (unsigned i = 0; i < KeySections.Size(); i++) { FKeySection *sect = &KeySections[i]; - DMenuItemBase *item = CreateOptionMenuItemStaticText(" ", false); + DMenuItemBase *item = CreateOptionMenuItemStaticText(" "); menu->mItems.Push(item); - item = CreateOptionMenuItemStaticText(sect->mTitle, true); + item = CreateOptionMenuItemStaticText(sect->mTitle, 1); menu->mItems.Push(item); for (unsigned j = 0; j < sect->mActions.Size(); j++) { diff --git a/src/namedef.h b/src/namedef.h index cc3e650883..3d8fd684f3 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -927,3 +927,14 @@ xx(MessageBoxMenu) xx(Both) xx(Physical) xx(Visual) + +xx(OptionMenuItemSubmenu) +xx(OptionMenuItemCommand) +xx(OptionMenuItemControlBase) +xx(OptionMenuItemOptionBase) +xx(OptionMenuSliderBase) +xx(OptionMenuFieldBase) +xx(OptionMenuItemColorPicker) +xx(OptionMenuItemStaticText) +xx(OptionMenuItemStaticTextSwitchable) +xx(mAction)