#pragma once #pragma region CPL License /* Nuclex Unreal Module Copyright (C) 2014-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #include #include #include "ParagraphInputSource.h" #include "../UI/DialogPlayerController.h" #include "VisualNovelPlayerController.generated.h" // --------------------------------------------------------------------------------------------- // /// Player controller that can deliver button input to dialogs and visual novel boxes /// @remarks /// This is an extension of the dialog player controller which is capable of controlling /// visual novel text boxes (called 'paragraphs' here because they're like paragraphs /// in a book's text). It can control dialogs (IButtonControllabelDialog), too. /// /// It can be used as-is for menus or inherited from to build mixed player controllers /// that can handle UI input as well as normal pawn controls (UI input can be switched /// of at any time using the @see EnableDialogInput property). UCLASS() class NUCLEX_API AVisualNovelPlayerController : public ADialogPlayerController, public IParagraphInputSource { GENERATED_BODY() /// Initializes a new player controller for visual novels public: AVisualNovelPlayerController(); // // AVisualNovelPlayerController implementation // /// Directly accepts a choice made by the player /// @param choiceIndex Index of the choice the player has made public: UFUNCTION(BlueprintCallable, Category="Visual Novel") void InjectAcceptChoice(int choiceIndex); /// Skips over the current paragraph unless it asks for a choice from the player public: UFUNCTION(BlueprintCallable, Category="Visual Novel") void InjectSkip(); // // ADialogPlayerController implementation // /// Binds the dialog controls to the default input actions if set up for the project public: virtual void BindToDefaultInputActions_Implementation() override; // // IParagraphInputSource implementation // /// Retrieves the visual novel box that input is currently being sent to /// @returns The visual novel box currently receiving input from this source public: virtual const TScriptInterface< IButtonControllableParagraph > GetActiveParagraph_Implementation() override; /// Selects the active visual novel box, enables UI input and shows the mouse cursor (unless VR) /// @param targetParagraph Visual novel box to which all UI input will be sent public: virtual void BeginParagraphInput_Implementation( const TScriptInterface &targetParagraph ) override; /// Disables viaual novel input and hides the mouse cursor public: virtual void EndParagraphInput_Implementation() override; // // IDialogInputSource implementation // /// Selects the active dialog, enables UI input and shows the mouse cursor (unless VR) /// @param targetDialog Dialog to which all UI input will be sent public: virtual void BeginDialogInput_Implementation( const TScriptInterface &targetDialog ) override; /// Disables UI input and hides the mouse cursor public: virtual void EndDialogInput_Implementation() override; // // Internal implementation // /// Directly accepts the first choice of the currently active dialog private: void firstChoiceAccepted(); /// Directly accepts the second choice of the currently active dialog private: void secondChoiceAccepted(); /// Directly accepts the third choice of the currently active dialog private: void thirdChoiceAccepted(); /// Directly accepts the fourth choice of the currently active dialog private: void fourthChoiceAccepted(); /// Directly accepts the fifth choice of the currently active dialog private: void fifthChoiceAccepted(); /// Dialog input is currently being sent to (can be null if no dialog is active) /// @remarks /// This is intentionally private. It's a cached property that may stay nullptr /// until one of the Inject() methods are actually called (specifically, this /// would happen if someone assigns the ADialogPlayerController::ActiveDialog /// property directly. /// /// Everything one could do with the active paragraph is covered by /// the Inject...() methods in this class, so there is no need to expose this. private: UPROPERTY(Transient) TScriptInterface activeParagraph; /// Whether the default input bindings for the dialog actions have been set up private: bool defaultDialogInputActionsBound; /// Last dialog for which the currently active paragraph was downcast /// @remarks /// Not an uproperty, we don't care if it gets garbage collected, we only want /// the pointer to compare the (properly GC-managed) active paragraph against. private: mutable UObject *dialogForWhichParagraphWasChecked; }; // --------------------------------------------------------------------------------------------- //