Skip to content

Commit

Permalink
Merge pull request The-Chinese-Room#108 from The-Chinese-Room/master
Browse files Browse the repository at this point in the history
Master
  • Loading branch information
TCR-Nick authored Sep 22, 2024
2 parents 3a5767b + 46cf0da commit a3ad959
Show file tree
Hide file tree
Showing 41 changed files with 2,308 additions and 306 deletions.
Binary file added Content/Inkpot/InkpotDebug.uasset
Binary file not shown.
Binary file added Content/Inkpot/Widgets/WBP_InkpotLineView.uasset
Binary file not shown.
Binary file not shown.
36 changes: 18 additions & 18 deletions Inkpot.uplugin
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"FileVersion": 1,
"Version": 1,
"VersionName": "1.03.21",
"VersionName": "1.10.21",
"FriendlyName": "Inkpot",
"Description": "A container for Ink in Unreal.",
"Category": "Scripting",
Expand All @@ -15,23 +15,23 @@
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "Inkpot",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "InkPlusPlus",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "InkpotEditor",
"Type": "Editor",
"LoadingPhase": "Default"
}
],
"Modules": [
{
"Name": "Inkpot",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "InkPlusPlus",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "InkpotEditor",
"Type": "Editor",
"LoadingPhase": "Default"
}
],
"Plugins": [
]
}
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
# Inkpot
**Inkpot** - An container for **Ink** within the Unreal Engine developed by [The Chinese Room](https://www.thechineseroom.co.uk/).<br><br>
This is a plugin for Unreal Engine 5.3 or later.<br>
The latest release is version **1.03.21** of the plugin.</br>
**Inkpot** - A container for **Ink** within the Unreal Engine developed by [The Chinese Room](https://www.thechineseroom.co.uk/).<br><br>
This is a plugin for Unreal Engine 5.4 or later.<br>
This is version **1.10.21** of the plugin.</br>
The head revision contains work in progress towards the upcoming release.<br>

Inkpot is a wrapper for the wonderful narrative scripting language **Ink** developed by [Inkle Studios](https://www.inklestudios.com/ink/).<br>

For a demo of how this integrates with an Unreal project see [the inkpot demo](https://github.com/The-Chinese-Room/InkpotDemo/).<br>
For a demo of how this integrates with an Unreal project (& a load more documentation) see [the inkpot demo](https://github.com/The-Chinese-Room/InkpotDemo/).<br>

For general support and chat with other users, check out [Inkle's discord](https://discord.com/invite/inkle#unreal-projects) <br>
(You'll find Inkpot chat in #unreal-projects)

## Changelog

### Changes in 1.10.21
Introducing the Blotter! or Inkpot Debugger, an Unreal editor utility widget that allows the viewing of and setting of Ink variables at runtime.<br>
Full support for Ink List creation & manipulation in blueprints.<br>
Added documentation to the headers for most blueprint facing functions, story, values & lists.<br>
Ink function evaluation now supported from Blueprints.<br>
Added variable existence checks. All setter or getter functions from story now report success, plus generic test function IsVariableDefined.<br>
Fixed crash when calling begin story with a null asset.<br>
Fixed crash when calling function with empty variable declarations.<br>

### Changes in 1.03.21
Added new abstract factory creation for stories, youclass UInkpotStory can now be subclassed on a per project basis.<br>
Switched settings back to regular UDeveloperSettings as backed by CVAR version did not seem to work.<br>
Expand Down Expand Up @@ -47,7 +58,7 @@ External functions are now implemented, along with functional tests.<br>
Initial release.<br>

## Requirements
Inkpot works with version 5.3 of Unreal.<br>
Inkpot works with version 5.4 of Unreal.<br>
Inkpot includes a C++ port of Ink-engine-runtime version 21, which can be found in the InkPlusPlus module.<br>

### .Net framework 5.0
Expand Down
7 changes: 6 additions & 1 deletion Source/InkPlusPlus/Private/Ink/CallStack.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "Ink/CallStack.h"
#include "Ink/CallStack.h"

#include "Utility/InkPlusPlusLog.h"
#include "Ink/Container.h"
Expand Down Expand Up @@ -208,6 +208,11 @@ Ink::FPointer Ink::FThread::GetPreviousPointer() const

void Ink::FThread::SetPreviousPointer(Ink::FPointer InPreviousPointer)
{
#ifdef TCR_DEBUG_DIVERTS
const FString ptrStr = InPreviousPointer.ToString();
UE_LOG(InkPlusPlus, Display, TEXT("PREVIOUS %p %s"), InPreviousPointer.GetContainer().Get(), *ptrStr); // Ink Pointer -> debug
#endif

PreviousPointer = InPreviousPointer;
}

Expand Down
6 changes: 6 additions & 0 deletions Source/InkPlusPlus/Private/Ink/ListDefinitionsOrigin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,9 @@ TArray<TSharedPtr<Ink::FListDefinition>> Ink::FListDefinitionsOrigin::GetLists()
Lists.GenerateValueArray(listOfLists);
return listOfLists;
}

void Ink::FListDefinitionsOrigin::AddListDefinition(TSharedPtr<Ink::FListDefinition> InOrigin)
{
Lists.Add( InOrigin->GetName(), InOrigin );
}

14 changes: 11 additions & 3 deletions Source/InkPlusPlus/Private/Ink/StoryState.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@


#include "Ink/StoryState.h"
#include "Utility/InkPlusPlusLog.h"
#include "Ink/Flow.h"
Expand Down Expand Up @@ -337,8 +337,11 @@ Ink::FPointer Ink::FStoryState::GetCurrentPointer() const

void Ink::FStoryState::SetCurrentPointer(Ink::FPointer InCurrentPointer)
{
//const FString ptrStr = InCurrentPointer.ToString();
//UE_LOG(InkPlusPlus, Display, TEXT("%s"), *ptrStr); // Ink Pointer -> debug
#ifdef TCR_DEBUG_DIVERTS
const FString ptrStr = InCurrentPointer.ToString();
UE_LOG(InkPlusPlus, Display, TEXT("%p %s"), InCurrentPointer.GetContainer().Get(), *ptrStr); // Ink Pointer -> debug
#endif

CallStack()->CurrentElement()->SetCurrentPointer(InCurrentPointer);
}

Expand Down Expand Up @@ -1202,6 +1205,11 @@ Ink::FPointer Ink::FStoryState::GetDivertedPointer()

void Ink::FStoryState::SetDivertedPointer(Ink::FPointer InDivertedPointer)
{
#ifdef TCR_DEBUG_DIVERTS
const FString ptrStr = InDivertedPointer.ToString();
UE_LOG(InkPlusPlus, Display, TEXT("DIVERT %p %s"), InDivertedPointer.GetContainer().Get(), *ptrStr); // Ink Pointer -> debug
#endif

DivertedPointer = InDivertedPointer;
}

Expand Down
60 changes: 40 additions & 20 deletions Source/InkPlusPlus/Private/Utility/InkPlusPlusUtility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,46 @@ namespace Ink
{
TSharedPtr<Ink::FObject> newObj;

if(InObj->CanCastTo(Ink::EInkObjectClass::FChoicePoint )) newObj = CopyInkObjectAs<Ink::FChoicePoint >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FContainer )) newObj = CopyInkObjectAs<Ink::FContainer >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FControlCommand )) newObj = CopyInkObjectAs<Ink::FControlCommand >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FDivert )) newObj = CopyInkObjectAs<Ink::FDivert >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FGlue )) newObj = CopyInkObjectAs<Ink::FGlue >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FNativeFunctionCall )) newObj = CopyInkObjectAs<Ink::FNativeFunctionCall >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FTag )) newObj = CopyInkObjectAs<Ink::FTag >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueBool )) newObj = CopyInkObjectAs<Ink::FValueBool >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueDivertTarget )) newObj = CopyInkObjectAs<Ink::FValueDivertTarget >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueFloat )) newObj = CopyInkObjectAs<Ink::FValueFloat >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueInt )) newObj = CopyInkObjectAs<Ink::FValueInt >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueList )) newObj = CopyInkObjectAs<Ink::FValueList >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueString )) newObj = CopyInkObjectAs<Ink::FValueString >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueVariablePointer)) newObj = CopyInkObjectAs<Ink::FValueVariablePointer>( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValue )) newObj = CopyInkObjectAs<Ink::FValue >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVariableAssignment )) newObj = CopyInkObjectAs<Ink::FVariableAssignment >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVariableReference )) newObj = CopyInkObjectAs<Ink::FVariableReference >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVoid )) newObj = CopyInkObjectAs<Ink::FVoid >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FObject )) newObj = CopyInkObjectAs<Ink::FObject >( InObj );
else UE_LOG( InkPlusPlus, Error, TEXT( "Attempt to copy Ink object of unknown type") );
if(InObj->CanCastTo(Ink::EInkObjectClass::FChoicePoint ))
newObj = CopyInkObjectAs<Ink::FChoicePoint >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FContainer ))
newObj = CopyInkObjectAs<Ink::FContainer >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FControlCommand ))
newObj = CopyInkObjectAs<Ink::FControlCommand >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FDivert ))
newObj = CopyInkObjectAs<Ink::FDivert >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FGlue ))
newObj = CopyInkObjectAs<Ink::FGlue >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FNativeFunctionCall ))
newObj = CopyInkObjectAs<Ink::FNativeFunctionCall >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FTag ))
newObj = CopyInkObjectAs<Ink::FTag >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueBool ))
newObj = CopyInkObjectAs<Ink::FValueBool >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueDivertTarget ))
newObj = CopyInkObjectAs<Ink::FValueDivertTarget >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueFloat ))
newObj = CopyInkObjectAs<Ink::FValueFloat >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueInt ))
newObj = CopyInkObjectAs<Ink::FValueInt >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueList ))
newObj = CopyInkObjectAs<Ink::FValueList >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueString ))
newObj = CopyInkObjectAs<Ink::FValueString >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValueVariablePointer))
newObj = CopyInkObjectAs<Ink::FValueVariablePointer>( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FValue ))
newObj = CopyInkObjectAs<Ink::FValue >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVariableAssignment ))
newObj = CopyInkObjectAs<Ink::FVariableAssignment >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVariableReference ))
newObj = CopyInkObjectAs<Ink::FVariableReference >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FVoid ))
newObj = CopyInkObjectAs<Ink::FVoid >( InObj );
else if(InObj->CanCastTo(Ink::EInkObjectClass::FObject ))
newObj = CopyInkObjectAs<Ink::FObject >( InObj );
else
UE_LOG( InkPlusPlus, Error, TEXT( "Attempt to copy Ink object of unknown type") );

return newObj;
}
Expand Down
6 changes: 4 additions & 2 deletions Source/InkPlusPlus/Public/Ink/ListDefinitionsOrigin.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Ink
{
class FValueList;

class FListDefinitionsOrigin
class INKPLUSPLUS_API FListDefinitionsOrigin
{
public:
FListDefinitionsOrigin() = delete;
Expand All @@ -18,7 +18,9 @@ namespace Ink
bool TryListGetDefinition(const FString& InName, TSharedPtr<FListDefinition>& OutListDefinition);
TSharedPtr<Ink::FValueList> FindSingleItemListWithName(const FString& InName);

INKPLUSPLUS_API TArray<TSharedPtr<FListDefinition>> GetLists() const;
TArray<TSharedPtr<FListDefinition>> GetLists() const;

void AddListDefinition(TSharedPtr<Ink::FListDefinition> InOrigin);

private:
TMap<FString, TSharedPtr<Ink::FListDefinition>> Lists;
Expand Down
9 changes: 6 additions & 3 deletions Source/Inkpot/Inkpot.Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ public Inkpot(ReadOnlyTargetRules Target) : base(Target)
"InkPlusPlus",

"DeveloperSettings",
}
}
);

PrivateDependencyModuleNames.AddRange(
new string[]
{
}
);
"Slate",
"SlateCore",
"UMG"
}
);

DynamicallyLoadedModuleNames.AddRange(
new string[]
Expand Down
5 changes: 4 additions & 1 deletion Source/Inkpot/Private/Inkpot/Inkpot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ UInkpotStory* UInkpot::BeginStory( UInkpotStoryAsset* InStory )
UInkpotStory* story = Stories->BeginStory( InStory );
if(EventOnStoryBegin.IsBound())
EventOnStoryBegin.Broadcast( story );
story->PostBegin();
return story;
}

Expand Down Expand Up @@ -96,3 +95,7 @@ void UInkpot::OnStartGameInstance( UGameInstance *InInstance )
GameInstance = InInstance;
}

UInkpotStory* UInkpot::GetStory( TSoftObjectPtr<UInkpotStoryAsset> InkpotStoryAssetPath)
{
return Stories->GetStory(InkpotStoryAssetPath);
}
11 changes: 11 additions & 0 deletions Source/Inkpot/Private/Inkpot/InkpotLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ void UInkpotLine::Initialise(const FString &InString)
String = InString;
// TODO : Localisation support here
Text = FText::FromString(String);
SetDirty(true);
}

const FString& UInkpotLine::GetString() const
Expand Down Expand Up @@ -38,3 +39,13 @@ const TArray<FString> &UInkpotLine::GetTagsInternal() const
UInkpotStory* story = GetStory();
return story->GetCurrentTags();
}

bool UInkpotLine::IsDirty()
{
return bIsDirty;
}

void UInkpotLine::SetDirty(bool bInIsDirty)
{
bIsDirty = bInIsDirty;
}
98 changes: 98 additions & 0 deletions Source/Inkpot/Private/Inkpot/InkpotList.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include "Inkpot/InkpotList.h"
#include "Inkpot/InkpotStory.h"
#include "Utility/InkpotLog.h"

static Ink::FInkList BADLIST;

FInkpotList::FInkpotList()
: FInkpotValue()
{
}

FInkpotList::FInkpotList(TSharedPtr<Ink::FValueType> InValue)
: FInkpotValue(InValue)
{
}

Ink::FInkList &FInkpotList::GetList() const
{
if ( IsValid() )
{
return Value->GetSubtype<Ink::FInkList>();
}
else
{
INKPOT_ERROR("List is invalid");
return BADLIST;
}
}

void FInkpotList::ToStringArray( TArray<FString>& OutValues, bool bUseOrigin ) const
{
OutValues.Reset();

Ink::FInkList &list = GetList();

TArray<Ink::FInkListItem> listItems;
list.GetKeys(listItems);
OutValues.Reserve( listItems.Num() );
for (Ink::FInkListItem& item : listItems)
{
FString entry;
if(bUseOrigin)
entry = FString::Printf( TEXT( "%s.%s" ), *item.OriginName, *item.ItemName );
else
entry = item.ItemName;

OutValues.Add( entry );
}
}

bool FInkpotList::ValidateOrigin( UInkpotStory *InStory ) const
{
Ink::FInkList &list = GetList();

// create a new origins array if non exists
TSharedPtr<TArray<TSharedPtr<Ink::FListDefinition>> >&origins = list.GetOrigins();
if( !origins.IsValid() )
origins = MakeShared<TArray<TSharedPtr<Ink::FListDefinition>>>();

for( auto &pair : list )
{
Ink::FInkListItem& item = pair.Key;
// check the items has an origin named in the story and that the item matches too
TSharedPtr<Ink::FListDefinition> origin = InStory->GetListOrigin( item.OriginName, item.ItemName );
if (!origin.IsValid())
return false;

// set correct value to that in the origin
pair.Value = origin->GetValueForItem( item );
origins->AddUnique( origin );
}

return true;
}

void FInkpotList::ToString( FString& OutValue, bool bInUseOrigin ) const
{
OutValue.Reset();

TArray<FString> items;
ToStringArray( items, bInUseOrigin );

FString delim(TEXT( ", "));

int len = 0;
for( FString &item : items )
len+=item.Len() + delim.Len();
OutValue.Reserve(len);

bool first = true;
for( FString &item : items )
{
if(!first)
OutValue.Append(delim);
first = false;
OutValue.Append(item);
}
}
Loading

0 comments on commit a3ad959

Please sign in to comment.