CDLC Menu for Mods

#HUD
Modified @ 2021-12-29 07:39:44

Two scripts that allow a mod to use the fancier CDLC menu instead of the default one!


NOTE: These scripts will be obsolete after the next update, as GfB are officially implementing a menu similar to the CDLC menu for regular mods.

This consists of two scripts:

  • a GameMod script, which is responsible for opening the...
  • ...Overlay HUD, which is responsible for rendering the CDLC menu.

These should be placed in .../HatinTime/HatinTimeGame/Mods/YourModFolder/Classes/ . These two classes obviously should be given unique names (both in the file name and inside of the script), so that it doesn't conflict with other mods that use this. (Because the GameMod script references the Overlay, you'll have to rename those references as well.)

If your mod already has a GameMod script, you'll need to merge them, since you can't have two GameMod scripts.

The Background, Logo, Splash Art, and an optional Titlecard can be set in OpenModManager (linked on the left-hand side of the page). Alternatively, you can set them manually in the modinfo.ini file (you can use the Vanessa's Curse modinfo as an example, in .../HatinTime/HatinTimeGame/CreatorDLC/VanessaCurseDLC/ ). Note that these images should be ".png"s because the game can't read transparency from ".jpg"s .

GamemodScript.uc

[RAW] [Download]

class GamemodScript extends GameMod;
 
event OnModLoaded()
{
    HookActorSpawn(class'Hat_HUDMenu_ModLevelSelect', 'Hat_HUDMenu_ModLevelSelect');
}
 
event OnHookedActorSpawn(Object NewActor, Name Identifier)
{
    local Hat_HUDMenu_ModLevelSelect ModsHUD;
    local Engine E;
    local int i;
    local Hat_HUD HatHUD;
 
    if (Identifier == 'Hat_HUDMenu_ModLevelSelect')
    {
        ModsHUD = Hat_HUDMenu_ModLevelSelect(NewActor);
        if (!ModsHUD.Open || ModsHUD.ModListMode == 2)
        {
            return;
        }
 
        //find the hud on which this hud was opened
        E = class'Engine'.static.GetEngine();
        for (i = 0; i < E.GamePlayers.Length; i++)
        {
            HatHUD = Hat_HUD(E.GamePlayers[i].Actor.MyHUD);
            if (HatHUD != None && HatHUD.m_hElements.Find(ModsHUD) != INDEX_NONE)
                break;
            else
                HatHUD = None;
        }
        if (HatHUD != None) OnModHUDOpened(HatHUD, ModsHUD);
    }
}
 
function OnModHUDOpened(Hat_HUD H, Hat_HUDMenu_ModLevelSelect ModsHUD)
{
    local OverlayHUD Overlay;
 
    //true, because it should be placed before the mods hud in the list, to get directional inputs first (whyyy are they fired first to last when literally any other input event doesn't???)
    Overlay = OverlayHUD(H.OpenHUD(class'OverlayHUD',, true));
    if (Overlay == None) return;
    Overlay.ModsHUD = ModsHUD;
    Overlay.InitHUD(H);
}
 
OverlayHUD.uc

[RAW] [Download]

class OverlayHUD extends Hat_HUDMenu
    DependsOn(Hat_HUDMenu_ModLevelSelect);
 
//    PROPERTIES START
 
//Set this to true if you want to remove the ripped paper from the top and bottom of the cdlc "screen"
var const bool RemoveRippedPaper;
 
var const bool ScanLineEffect;
 
var const bool ShineEffect;
 
//    PROPERTIES END
 
var Hat_HUDMenu_ModLevelSelect ModsHUD;
var bool IsPreviewingThisMod;
var int OriginalRenderingMode;
 
//called by the gamemod after the mod hud was opened and ModsHUD gets set.
event InitHUD(Hat_HUD H)
{
    ModsHUD.PushOnHUDElementClosedDelegate(OnModHUDClosed);
 
    if (RemoveRippedPaper)
        ModsHUD.BackgroundRippedPaper = Texture2D'EngineResources.Textures.TransparentTexture';
}
 
event OnModHUDClosed(HUD H, Hat_HUDElement e)
{
    //close yourself
    CloseHUD(H, self.class);
}
 
//happens after closing
function CleanUp()
{
    Super.CleanUp();
 
    //get rid of the reference once it gets closed, so it can be properly garbage collected
    ModsHUD = None;
}
 
event bool Tick(HUD H, float DeltaTime)
{
    local bool Previewing;
 
    if (!Super.Tick(H, DeltaTime)) return false;
 
    Previewing = ModsHUD.Preview && ModsHUD.PreviewMod.ScriptPackageName == String(class.Outer);
    if (IsPreviewingThisMod != Previewing)
    {
        PrePreviewStateChanged(H, Previewing);
        IsPreviewingThisMod = Previewing;
    }
 
    if (IsPreviewingThisMod)
    {
        //because the og hud is turned off, i had to copy-paste some essencial stuff here
 
        if (!ModsHUD.IsLoadingMap)
            ModsHUD.ReactivateMouseCheck(H);
 
        MouseActivated = ModsHUD.MouseActivated;
 
        if (ModsHUD.UndoPreview)
            ModsHUD.ExitPreview();
        else
            ModsHUD.PreviewTime += DeltaTime;
 
        if (ModsHUD.ClickDelay > 0)
        {
            ModsHUD.ClickDelay -= DeltaTime;
            if (ModsHUD.ClickDelay < 0)
                ModsHUD.ClickDelay = 0;
        }
 
        if (ModsHUD.IsCredits && ModsHUD.CreditsList.Length > 10)
        {
            ModsHUD.TextScrollOffset = (ModsHUD.TextScrollOffset + DeltaTime) % (float(ModsHUD.CreditsList.Length));
        }
    }
 
    return true;
}
 
event PrePreviewStateChanged(HUD H, bool newPreviewing)
{
    if (newPreviewing)
    {
        PlayOwnerSound(H, ModsHUD.CreatorDLCChangeChannel);
 
        ModsHUD.PreviewLogo = class'GameMod'.static.GetModIcon(ModsHUD.PreviewMod, 'Logo');
        ModsHUD.PreviewSplashArt = class'GameMod'.static.GetModIcon(ModsHUD.PreviewMod, 'SplashArt');
        ModsHUD.PreviewBackgroundArt = class'GameMod'.static.GetModIcon(ModsHUD.PreviewMod, 'Background');
        ModsHUD.PreviewTitlecard = class'GameMod'.static.GetModIcon(ModsHUD.PreviewMod, 'Titlecard');
        if (ModsHUD.PreviewInstance != None && ModsHUD.PreviewBackgroundArt != None)
        {
            ModsHUD.PreviewInstance.SetParent(Material'HatinTime_CreatorDLC.Materials.CreatorDLCBackground');
            ModsHUD.PreviewInstance.SetTextureParameterValue('Background', ModsHUD.PreviewBackgroundArt);
        }
 
        OriginalRenderingMode = ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].SpecialRenderingMode;
        ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].SpecialRenderingMode = 2;
 
        ModsHUD.UpdatePreviewButtons(H);
 
        //Removing the Enable/Disable button here since, with the Play Intro button, there ended up being 3 buttons, one of them ending up outside of the "screen"
        //Though if you want it back, just comment this line.
        ModsHUD.PreviewButtons.RemoveItem(LevelPreview_Enable);
 
        if (ScanLineEffect)
            ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].Overlay.AddItem(Material'HatinTime_CreatorDLC.Materials.CreatorDLCOverlayScanline');
        if (ShineEffect)
            ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].Overlay.AddItem(Material'HatinTime_CreatorDLC.Materials.CreatorDLCOverlayShine');
    }
    else
    {
        ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].SpecialRenderingMode = OriginalRenderingMode;
        ModsHUD.ModMenuTabs[ModsHUD.CurrentModMenuIndex].Overlay.Length = 0;
    }
 
    //Toggling the og hud so it doesn't get rendered when our mod is selected.
    Hat_HUD(H).SetElementEnabled(class'Hat_HUDMenu_ModLevelSelect', !newPreviewing);
}
 
//Copy-pasted the essential stuff for rendering the cdlc menu
event bool Render(HUD H)
{
    local float scale, alpha;
    local int ModListMode;
 
    if (!IsPreviewingThisMod || !Super.Render(H)) return false;
 
    scale = FMin(H.Canvas.ClipX / 1600, H.Canvas.ClipY / 900);
    alpha = 1 - ((1 - FClamp(ModsHUD.PreviewTime/ 0.25f,0,1)) ** 2);
 
    // Background
    H.Canvas.SetDrawColor(0,0,0,180);
    H.Canvas.SetPos(0,0);
    H.Canvas.DrawRect(H.Canvas.ClipX, H.Canvas.ClipY);
 
    H.Canvas.SetDrawColor(255,255,255,255*alpha);
    ModsHUD.ApplyFont(H, true);
 
    ModsHUD.MouseClear = true;
 
    ModListMode = ModsHUD.ModListMode;
    ModsHUD.ModListMode = 2;
    ModsHUD.RenderPreviewDLC(H, scale, alpha);
    ModsHUD.ModListMode = ModListMode;
 
    if (ModsHUD.PreviewMod.WorkshopId > 0 && !ModsHUD.IsCredits)
    {
        ModsHUD.DrawThumb(H, true, Scale*480, Scale*670, Scale*75, Scale*82.5);
        ModsHUD.DrawThumb(H, false, Scale*580, Scale*670, Scale*75, Scale*82.5);
    }
 
    if (ModsHUD.MouseClear && !Hat_HUD(H).IsGamepad() && MouseActivated)
    {
        ModsHUD.WipeAllSelections();
    }
    if (ModsHUD.IsMenuFrozen)
    {
        H.Canvas.SetDrawColor(0,0,0,180);
        H.Canvas.SetPos(0,0);
        H.Canvas.DrawRect(H.Canvas.ClipX, H.Canvas.ClipY);
    }
 
    return true;
}
 
function bool OnPressUp(HUD H, bool menu, bool release)
{
    if (IsPreviewingThisMod && ModsHUD.OnPressUp(H, menu, release))
    {
        MouseActivated = ModsHUD.MouseActivated;
        return true;
    }
    return false;
}
 
function bool OnPressDown(HUD H, bool menu, bool release)
{
    if (IsPreviewingThisMod && ModsHUD.OnPressDown(H, menu, release))
    {
        MouseActivated = ModsHUD.MouseActivated;
        return true;
    }
    return false;
}
 
function bool OnPressLeft(HUD H, bool menu, bool release)
{
    if (IsPreviewingThisMod)
    {
        if (ModsHUD.SelectedButton == LevelPreview_ThumbsUp || (ModsHUD.PreviewButtons.Find(ModsHUD.SelectedButton) == 0 && ModsHUD.PreviewMod.WorkshopId <= 0))
        {
            ModsHUD.SelectedButton = (ModsHUD.CreditsList.Length > 0 && ModsHUD.PreviewButtons.Find(LevelPreview_Credits) == INDEX_NONE) ? LevelPreview_Credits : LevelPreview_Back;
 
            ModsHUD.SetMouseHidden(H,true);
            ModsHUD.PlaySelectionChangedSound(H);
            ModsHUD.PreviewButtonsInterp = 0;
            ModsHUD.SelectedWorkshopBrowse = false;
        }
        else if (!ModsHUD.OnPressLeft(H, menu, release))
            return false;
 
        MouseActivated = ModsHUD.MouseActivated;
        return true;
    }
    return false;
}
 
function bool OnPressRight(HUD H, bool menu, bool release)
{
    local EModLevelPreviewButton RightmostLeftButton;
 
    if (IsPreviewingThisMod)
    {
        //the compiler threw a tantrum when i put this directly in the if :/
        RightmostLeftButton = (ModsHUD.CreditsList.Length > 0 && ModsHUD.PreviewButtons.Find(LevelPreview_Credits) == INDEX_NONE) ? LevelPreview_Credits : LevelPreview_Back;
 
        if (ModsHUD.SelectedButton == RightmostLeftButton && ModsHUD.PreviewMod.WorkshopId > 0)
        {
            ModsHUD.SelectedButton = LevelPreview_ThumbsUp;
 
            ModsHUD.SetMouseHidden(H,true);
            ModsHUD.PlaySelectionChangedSound(H);
            ModsHUD.PreviewButtonsInterp = 0;
            ModsHUD.SelectedWorkshopBrowse = false;
        }
        else if (!ModsHUD.OnPressRight(H, menu, release))
                return false;
 
        MouseActivated = ModsHUD.MouseActivated;
        return true;
    }
    return false;
}
 
function bool OnClick(HUD H, bool release)
{
    if (IsPreviewingThisMod) return ModsHUD.OnClick(H, release);
    else return false;
}
 
function bool OnAltClick(HUD H, bool release)
{
    if (IsPreviewingThisMod) return ModsHUD.OnAltClick(H, release);
    else return false;
}
 
defaultproperties
{
    ScanLineEffect = true
    ShineEffect = true
 
    RequiresMouse = true
    RealTime = true
}