- 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.
This commit is contained in:
Christoph Oelckers 2017-06-11 22:30:40 +02:00
parent ee3d73478a
commit f1ad42c4e5
4 changed files with 89 additions and 8 deletions

View file

@ -1121,7 +1121,7 @@ DEFINE_FIELD(FOptionMenuSettings, mLinespacing)
struct IJoystickConfig; struct IJoystickConfig;
// These functions are used by dynamic menu creation. // 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 c = PClass::FindClass("OptionMenuItemStaticText");
auto p = c->CreateNew(); auto p = c->CreateNew();

View file

@ -109,6 +109,7 @@ extern FSavegameManager savegameManager;
class DMenu; class DMenu;
extern DMenu *CurrentMenu; extern DMenu *CurrentMenu;
extern int MenuTime; extern int MenuTime;
class DMenuItemBase;
//============================================================================= //=============================================================================
// //
@ -125,18 +126,17 @@ public:
FString mNetgameMessage; FString mNetgameMessage;
PClass *mClass = nullptr; PClass *mClass = nullptr;
bool mProtected = false; bool mProtected = false;
TArray<DMenuItemBase *> mItems;
virtual size_t PropagateMark() { return 0; } virtual size_t PropagateMark() { return 0; }
}; };
class DMenuItemBase;
class DListMenuDescriptor : public DMenuDescriptor class DListMenuDescriptor : public DMenuDescriptor
{ {
DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor) DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor)
public: public:
TArray<DMenuItemBase *> mItems;
int mSelectedItem; int mSelectedItem;
double mSelectOfsX; double mSelectOfsX;
double mSelectOfsY; double mSelectOfsY;
@ -187,7 +187,6 @@ class DOptionMenuDescriptor : public DMenuDescriptor
DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor) DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor)
public: public:
TArray<DMenuItemBase *> mItems;
FString mTitle; FString mTitle;
int mSelectedItem; int mSelectedItem;
int mDrawTop; int mDrawTop;
@ -350,7 +349,7 @@ void M_MarkMenus();
struct IJoystickConfig; 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 * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int center);
DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings); DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings);
DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy); DMenuItemBase * CreateOptionMenuItemJoyConfigMenu(const char *label, IJoystickConfig *joy);

View file

@ -516,6 +516,52 @@ static bool CheckCompatible(DMenuDescriptor *newd, DMenuDescriptor *oldd)
return newd->mClass->IsDescendantOf(oldd->mClass); 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) static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc)
{ {
DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName); DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName);
@ -523,7 +569,32 @@ static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc)
{ {
if ((*pOld)->mProtected) 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; return true;
} }
@ -1400,9 +1471,9 @@ static void InitKeySections()
for (unsigned i = 0; i < KeySections.Size(); i++) for (unsigned i = 0; i < KeySections.Size(); i++)
{ {
FKeySection *sect = &KeySections[i]; FKeySection *sect = &KeySections[i];
DMenuItemBase *item = CreateOptionMenuItemStaticText(" ", false); DMenuItemBase *item = CreateOptionMenuItemStaticText(" ");
menu->mItems.Push(item); menu->mItems.Push(item);
item = CreateOptionMenuItemStaticText(sect->mTitle, true); item = CreateOptionMenuItemStaticText(sect->mTitle, 1);
menu->mItems.Push(item); menu->mItems.Push(item);
for (unsigned j = 0; j < sect->mActions.Size(); j++) for (unsigned j = 0; j < sect->mActions.Size(); j++)
{ {

View file

@ -927,3 +927,14 @@ xx(MessageBoxMenu)
xx(Both) xx(Both)
xx(Physical) xx(Physical)
xx(Visual) xx(Visual)
xx(OptionMenuItemSubmenu)
xx(OptionMenuItemCommand)
xx(OptionMenuItemControlBase)
xx(OptionMenuItemOptionBase)
xx(OptionMenuSliderBase)
xx(OptionMenuFieldBase)
xx(OptionMenuItemColorPicker)
xx(OptionMenuItemStaticText)
xx(OptionMenuItemStaticTextSwitchable)
xx(mAction)