I am currently working on making an interface for player to make actions (for turn-based rpg… fallout etc.). Currently I made so that player could store actions and accordingly execute them in a triggered combat mode, as far as this is still pretty much wip, decision and action phases basically do nothing (will later implement). So, I made a new empty class ICombatAction to be used as an interface, aswell TestCombatAction, and later on I’d implement IDecisionMaker, TestDecisionMaker – classes for both, action decision phase and for action execution phase… Currenty this probably doesn’t make much sense, but that’s not the point of the question anyway.
Now, everything went fine and dandy until I tried to compile the project. Even though from IDE editor there really didn’t seem to be any errors, I got swarmed with them in the TempLog after I tried to compile them in Unreal Engine:
Candidate modules for hot reload:
UnrealRPG
Launching UnrealBuildTool... [F:/Program Files/Epic Games/UE_4.16/Engine/Binaries/DotNET/UnrealBuildTool.exe UnrealRPG -ModuleWithSuffix UnrealRPG 6875 Win64 Development -editorrecompile -canskiplink "F:/Unreal Projects/UnrealRPG/UnrealRPG.uproject" ]
Warning: Starting HotReload took 0.0s.
CompilerResultsLog: New page: Compilation - Aug 30, 2017, 3:16:38 AM
CompilerResultsLog: Info Compiling game modules for hot reload
CompilerResultsLog: Info Performing 6 actions (4 in parallel)
CompilerResultsLog: Info GameCharacter.cpp
CompilerResultsLog: Info TestCombatAction.cpp
CompilerResultsLog:Error: Error F:\Unreal Projects\UnrealRPG\Source\UnrealRPG\GameCharacter.cpp(67) : error C2061: syntax error: identifier 'TestCombatAction'
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C2143: syntax error: missing ';' before '*'
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C2238: unexpected token(s) preceding ';'
CompilerResultsLog: Info ICombatAction.cpp
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C2143: syntax error: missing ';' before '*'
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
CompilerResultsLog:Error: Error f:\unreal projects\unrealrpg\source\unrealrpg\GameCharacter.h(27) : error C2238: unexpected token(s) preceding ';'
CompilerResultsLog: Info CombatEngine.cpp
CompilerResultsLog: Info ERROR: UBT ERROR: Failed to produce item: F:\Unreal Projects\UnrealRPG\Binaries\Win64\UE4Editor-UnrealRPG-6875.dll
CompilerResultsLog: Info Total build time: 14.90 seconds (Local executor: 0.00 seconds)
LogMainFrame: MainFrame: Module compiling took 15.632 seconds
Warning: HotReload failed, recompile failed
Now I’m not even sure what is causing some of these problems. I tried everything to fix them, but with no avail. + As far as I’m not an expert at Interfaces, especially Turn-Based ones and in UE, I found some resources from which I tried to adapt. I’m sure that they we’re pretty outdated, because in the process of writing I had to change some of the code, aswell - replace some obsolete functions with new ones.
For better understanding, here are the files described in the TempLog:
#ICombatAction.h
#pragma once
#include "CoreMinimal.h"
#include "GameCharacter.h"
class UGameCharacter;
class ICombatAction
{
public:
virtual void BeginExecuteAction(UGameCharacter* character) = 0;
virtual bool ExecuteAction(float DeltaSeconds) = 0;
};
#TestCombatAction.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "ICombatAction.h"
class TestCombatAction : public ICombatAction
{
protected:
float delayTimer;
public:
virtual void BeginExecuteAction(UGameCharacter* character) override;
virtual bool ExecuteAction(float DeltaSeconds) override;
};
#TestCombatAction.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "TestCombatAction.h"
#include "UnrealRPG.h"
void TestCombatAction::BeginExecuteAction(UGameCharacter* character)
{
UE_LOG(LogTemp, Log, TEXT("%s does nothing"), *character->CharacterName);
this->delayTimer = 1.0f;
}
bool TestCombatAction::ExecuteAction(float DeltaSeconds)
{
this->delayTimer -= DeltaSeconds;
return this->delayTimer <= 0.0f;
}
And now the class files directly affected
#GameCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "FCharacterInfo.h"
#include "FCharacterClassInfo.h"
#include "FEnemyInfo.h"
#include "ICombatAction.h"
#include "GameCharacter.generated.h"
class CombatEngine;
UCLASS(BlueprintType)
class UNREALRPG_API UGameCharacter : public UObject
{
GENERATED_BODY()
UGameCharacter(const class FObjectInitializer& objectInitializer);
public:
ICombatAction* combatAction; // expected a type specifier and ; before *
FCharacterClassInfo* ClassInfo;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
FString CharacterName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 MHP;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 MMP;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 HP;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 MP;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 ATK;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 DEF;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterInfo")
int32 LUCK;
static UGameCharacter* CreateGameCharacter(FCharacterInfo* characterInfo, UObject* outer);
static UGameCharacter* CreateGameCharacter(FEnemyInfo* enemyInfo, UObject* outer);
void BeginDestroy() override;
//protected
//float testDelayTimer;
public:
CombatEngine* combatInstance;
void BeginMakeDecision();
bool MakeDecision(float DeltaSeconds);
void BeginExecuteAction();
bool ExecuteAction(float DeltaSeconds);
};
#GameCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "GameCharacter.h"
#include "CombatEngine.h"
UGameCharacter::UGameCharacter(const class FObjectInitializer& objectInitializer) : Super(objectInitializer)
{
}
UGameCharacter* UGameCharacter::CreateGameCharacter(FCharacterInfo* characterInfo, UObject* Outer)
{
UGameCharacter* character = NewObject<UGameCharacter>(Outer);
// Locate character classes asset
UDataTable* characterClasses = Cast<UDataTable>(StaticLoadObject(UDataTable::StaticClass(), NULL, TEXT("DataTable'/Game/Other/CharacterClassInfoDT.CharacterClassInfoDT'")));
if (characterClasses == NULL)
{
UE_LOG(LogTemp, Error, TEXT("Character Classes Datatable not found!"));
}
else
{
character->CharacterName = characterInfo->Character_Name;
FCharacterClassInfo* row = characterClasses->FindRow<FCharacterClassInfo>(*(characterInfo->Class_ID), TEXT("LookupCharacterClass"));
character->ClassInfo = row;
character->MHP = character->ClassInfo->StartMHP;
character->MMP = character->ClassInfo->StartMMP;
character->HP = character->MHP;
character->MP = character->MMP;
character->ATK = character->ClassInfo->StartATK;
character->DEF = character->ClassInfo->StartDEF;
character->LUCK = character->ClassInfo->StartLuck;
}
return character;
}
UGameCharacter* UGameCharacter::CreateGameCharacter(FEnemyInfo* enemyInfo, UObject* outer)
{
UGameCharacter* character = NewObject<UGameCharacter>(outer);
character->CharacterName = enemyInfo->EnemyName;
character->ClassInfo = nullptr;
character->MHP = enemyInfo->MHP;
character->MMP = 0;
character->HP = enemyInfo->MHP;
character->MP = 0;
character->ATK = enemyInfo->ATK;
character->DEF = enemyInfo->DEF;
character->LUCK = enemyInfo->LUCK;
return character;
}
void UGameCharacter::BeginMakeDecision()
{
UE_LOG(LogTemp, Log, TEXT("Character %s making decision"), *(this->CharacterName));
this->combatAction = new TestCombatAction(); // expected a type specifier
}
bool UGameCharacter::MakeDecision(float DeltaSeconds)
{
return true;
}
void UGameCharacter::BeginExecuteAction()
{
this->combatAction->BeginExecuteAction(this);
}
bool UGameCharacter::ExecuteAction(float DeltaSeconds)
{
bool finishedAction = this->combatAction->ExecuteAction(DeltaSeconds);
if (finishedAction)
{
delete(this->combatAction);
return true;
}
return false;
}
void UGameCharacter::BeginDestroy()
{
Super::BeginDestroy();
}