ScreenStackSubClasses

Tracking Issue: #290

Tags: compatibility

A number of functions in UIScreenStack operate on classes, but fail to consider subclasses. This causes subtle bugs in base game and mod code that fails to consider the possibility that a given class can be subclassed/overridden. For example, UIArmory does something like this:

// Don't allow jumping to the geoscape from the armory when coming from squad select
if (!`ScreenStack.IsInStack(class'UISquadSelect'))
{
    NavHelp.AddGeoscapeButton();
}

However, if UISquadSelect is being overridden or replaced, this can cause the campaign to permanently deadlock because UIArmory fails to find the changed squad select screen. The proper fix would be using HasInstanceOf, but this error is extremely common in base game and mod code. As a result, it was decided that the best fix is to change all functions in UIScreenStack to always consider subclasses. A full list of affected functions:

  • GetScreen
  • IsCurrentClass
  • IsInStack
  • IsNotInStack

Compatibility

If you legitimately want to not consider subclasses, you can use the functions

function UIScreen GetScreen_CH(class<UIScreen> ScreenClass, bool IncludeSubTypes);
function bool IsCurrentClass_CH(class<UIScreen> ScreenClass, bool IncludeSubTypes);

and rewrite IsInStack/IsNotInStack in terms of GetScreen_CH(...) !=/== none.

Source code references