Compare commits
No commits in common. "6b59f5a2b63fcb5d2e5587151685cea14c1d160c" and "739e9b398114aea25715e487958ab194bb314a3b" have entirely different histories.
6b59f5a2b6
...
739e9b3981
4 changed files with 2 additions and 289 deletions
|
|
@ -1,5 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
[Audio]
|
[Audio]
|
||||||
UseAudioMixer=True
|
UseAudioMixer=True
|
||||||
|
|
||||||
|
|
@ -175,7 +174,7 @@ bOffsetPlayerGamepadIds=False
|
||||||
GameInstanceClass=/Script/Engine.GameInstance
|
GameInstanceClass=/Script/Engine.GameInstance
|
||||||
GameDefaultMap=/Game/Levels/Main.Main
|
GameDefaultMap=/Game/Levels/Main.Main
|
||||||
ServerDefaultMap=/Engine/Maps/Entry.Entry
|
ServerDefaultMap=/Engine/Maps/Entry.Entry
|
||||||
GlobalDefaultGameMode=/Script/minicook.minicookGameModeBase
|
GlobalDefaultGameMode=/Script/Engine.GameModeBase
|
||||||
GlobalDefaultServerGameMode=None
|
GlobalDefaultServerGameMode=None
|
||||||
|
|
||||||
[/Script/Slate.SlateSettings]
|
[/Script/Slate.SlateSettings]
|
||||||
|
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
// Stefan Stefanov 2023
|
|
||||||
|
|
||||||
|
|
||||||
#include "OvenPawn.h"
|
|
||||||
|
|
||||||
auto FCookstove::Setup(const UDataTable *DataTablePtr, const int32 MealID,
|
|
||||||
const double InUndercookedMultiplier,
|
|
||||||
const double InOvercookedMultiplier,
|
|
||||||
const double InScoreMultiplier) -> bool
|
|
||||||
{
|
|
||||||
// Set the current meal id
|
|
||||||
CurrentMealID = MealID;
|
|
||||||
CurrentlyCooking = true;
|
|
||||||
// Get the meal from the provided RecipesDataTable
|
|
||||||
Meal = GetMealFromTable(DataTablePtr, MealID);
|
|
||||||
if (Meal.ID == -1)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Error, TEXT("Couldn't find a meal with ID: %d"), MealID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetCookingTime(FTimespan::FromMilliseconds(Meal.TotalCookingTimeMS));
|
|
||||||
TargetHeat = FMath::Clamp(Meal.TargetHeat, 0.0, 1.0);
|
|
||||||
HeatHalfRange = FMath::Clamp(Meal.HeatHalfRange, 0.0, 1.0);
|
|
||||||
|
|
||||||
this->UndercookedMultiplier = InUndercookedMultiplier;
|
|
||||||
this->OvercookedMultiplier = InOvercookedMultiplier;
|
|
||||||
this->ScoreMultiplier = InScoreMultiplier;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto FCookstove::GetMealFromTable(const UDataTable *DataTablePtr, const int32 MealID) -> FMeal
|
|
||||||
{
|
|
||||||
if (DataTablePtr == nullptr || MealID < 0)
|
|
||||||
return FMeal{};
|
|
||||||
|
|
||||||
const FName MealRowName = DataTablePtr->GetRowNames()[MealID];
|
|
||||||
FMeal *Meal = DataTablePtr->FindRow<FMeal>(MealRowName, "");
|
|
||||||
|
|
||||||
return *Meal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FCookstove::SetCookingTime(const FTimespan CookingTimespan)
|
|
||||||
{
|
|
||||||
StartTime = FDateTime::Now();
|
|
||||||
EndTime = StartTime + CookingTimespan;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FCookstove::Update(const float DeltaTime, int32 &PlayerScore)
|
|
||||||
{
|
|
||||||
// If the id is not set, we have no work
|
|
||||||
if (CurrentMealID == -1 || CurrentlyCooking == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// HeatHalfRange can be used to calculate an acceptable range
|
|
||||||
if (CurrentHeat < TargetHeat - HeatHalfRange)
|
|
||||||
{
|
|
||||||
CookingStats.TotalTimeUndercookedMS += DeltaTime;
|
|
||||||
}
|
|
||||||
else if (CurrentHeat > TargetHeat + HeatHalfRange)
|
|
||||||
{
|
|
||||||
CookingStats.TotalTimeOvercookedMS += DeltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsMealDone())
|
|
||||||
PlayerScore += FinishMeal();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto FCookstove::GetRemainingCookingTime() const -> FTimespan
|
|
||||||
{
|
|
||||||
const FDateTime Now = FDateTime::Now();
|
|
||||||
if (Now >= EndTime)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
return (EndTime - Now).GetTotalMilliseconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto FCookstove::IsMealDone() const -> bool
|
|
||||||
{
|
|
||||||
return GetRemainingCookingTime() == 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto FCookstove::FinishMeal() -> int32
|
|
||||||
{
|
|
||||||
CookingStats.TotalCookedMeals++;
|
|
||||||
CurrentlyCooking = false;
|
|
||||||
|
|
||||||
// Calculate the score based on multipliers
|
|
||||||
int32 Score{0};
|
|
||||||
Score += CookingStats.TotalTimeUndercookedMS * UndercookedMultiplier;
|
|
||||||
Score += CookingStats.TotalTimeOvercookedMS * OvercookedMultiplier;
|
|
||||||
Score +=
|
|
||||||
(Meal.TotalCookingTimeMS - (CookingStats.TotalTimeOvercookedMS + CookingStats.TotalTimeUndercookedMS))
|
|
||||||
* ScoreMultiplier;
|
|
||||||
return Score;
|
|
||||||
}
|
|
||||||
|
|
||||||
AOvenPawn::AOvenPawn()
|
|
||||||
{
|
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOvenPawn::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
// Setup the cookstove related items
|
|
||||||
Cookstoves.AddDefaulted(CookstoveObjects.Num());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AOvenPawn::Tick(float DeltaTime)
|
|
||||||
{
|
|
||||||
Super::Tick(DeltaTime);
|
|
||||||
|
|
||||||
int32 ScoreThisFrame{0};
|
|
||||||
// Check the cooking stoves and update 'em
|
|
||||||
for (FCookstove Cookstove : Cookstoves)
|
|
||||||
{
|
|
||||||
Cookstove.Update(DeltaTime, ScoreThisFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentPlayerScore += ScoreThisFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called to bind functionality to input
|
|
||||||
void AOvenPawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent)
|
|
||||||
{
|
|
||||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
auto AOvenPawn::TrySpawningNewRandomMeal() -> bool
|
|
||||||
{
|
|
||||||
bool bSuccess{false};
|
|
||||||
for (FCookstove Cookstove : Cookstoves)
|
|
||||||
{
|
|
||||||
if (!Cookstove.CurrentlyCooking)
|
|
||||||
{
|
|
||||||
const int32 MealID = FMath::RandRange(0, RecipesDataTable->GetRowNames().Num());
|
|
||||||
bSuccess = Cookstove
|
|
||||||
.Setup(RecipesDataTable, MealID,
|
|
||||||
UndercookedMultiplier,
|
|
||||||
OvercookedMultiplier,
|
|
||||||
ScoreMultiplier);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bSuccess;
|
|
||||||
}
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
// Stefan Stefanov 2023
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "GameFramework/Pawn.h"
|
|
||||||
#include "Misc/DateTime.h"
|
|
||||||
#include "Misc/Timespan.h"
|
|
||||||
#include "Engine/DataTable.h"
|
|
||||||
|
|
||||||
#include "OvenPawn.generated.h"
|
|
||||||
|
|
||||||
USTRUCT()
|
|
||||||
struct FMeal : public FTableRowBase
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
int32 ID{-1};
|
|
||||||
FString MealName;
|
|
||||||
double TargetHeat{0.0};
|
|
||||||
double HeatHalfRange{0.0};
|
|
||||||
double TotalCookingTimeMS{0.0};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FCookingStats
|
|
||||||
{
|
|
||||||
int32 TotalCookedMeals{0};
|
|
||||||
int32 TotalTimeUndercookedMS{0};
|
|
||||||
int32 TotalTimeOvercookedMS{0};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FCookstove
|
|
||||||
{
|
|
||||||
// MealID from the data table
|
|
||||||
int32 CurrentMealID{-1};
|
|
||||||
FMeal Meal;
|
|
||||||
|
|
||||||
// When the meal started cooking
|
|
||||||
FDateTime StartTime;
|
|
||||||
// and when it should be done cooking
|
|
||||||
FDateTime EndTime;
|
|
||||||
bool CurrentlyCooking{false};
|
|
||||||
|
|
||||||
// Should always be in the range [0.0, 1.0]
|
|
||||||
double TargetHeat{0.5};
|
|
||||||
double HeatHalfRange{0.15};
|
|
||||||
double CurrentHeat{0.0};
|
|
||||||
|
|
||||||
double UndercookedMultiplier{1.0};
|
|
||||||
double OvercookedMultiplier{1.0};
|
|
||||||
double ScoreMultiplier{1.0};
|
|
||||||
|
|
||||||
FCookingStats CookingStats{};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Given a @param DataTablePtr and a @param MealID, configure the cookstove to start cooking the meal.
|
|
||||||
* @return Returns whether we found a meal with the provided @param MealID and successfully started cooking it.
|
|
||||||
*/
|
|
||||||
auto Setup(const UDataTable *DataTablePtr,
|
|
||||||
const int32 MealID,
|
|
||||||
const double InUndercookedMultiplier,
|
|
||||||
const double InOvercookedMultiplier,
|
|
||||||
const double InScoreMultiplier) -> bool;
|
|
||||||
|
|
||||||
static auto GetMealFromTable(const UDataTable *DataTablePtr, int32 MealID) -> FMeal;
|
|
||||||
|
|
||||||
void SetCookingTime(const FTimespan CookingTimespan);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Updates the cookstove for this tick, if a meal is cooking, updates the stats for it and if it finishes it calculates the score, etc...
|
|
||||||
* @param DeltaTime Time between N-1 and N-2 frames in milliseconds
|
|
||||||
* @param PlayerScore Takes in the current player score in case a meal gets finished and the score must be returned
|
|
||||||
*/
|
|
||||||
void Update(const float DeltaTime, int32 &PlayerScore);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the remaining cooking time
|
|
||||||
*/
|
|
||||||
auto GetRemainingCookingTime() const -> FTimespan;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the currently cooked meal is done cooking
|
|
||||||
*/
|
|
||||||
auto IsMealDone() const -> bool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Finishes up cooking the current meal, setting up the necessary stats and state
|
|
||||||
* @return Returns the calculated score based on the stats of the cooked meal
|
|
||||||
*/
|
|
||||||
auto FinishMeal() -> int32;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class MINICOOK_API AOvenPawn : public APawn
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
AOvenPawn();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual void Tick(float DeltaTime) override;
|
|
||||||
|
|
||||||
// Called to bind functionality to input
|
|
||||||
virtual void SetupPlayerInputComponent(class UInputComponent *PlayerInputComponent) override;
|
|
||||||
|
|
||||||
bool TrySpawningNewRandomMeal();
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Oven Settings")
|
|
||||||
double ScoreMultiplier{1.0};
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Oven Settings")
|
|
||||||
double UndercookedMultiplier{1.0};
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Oven Settings")
|
|
||||||
double OvercookedMultiplier{1.0};
|
|
||||||
|
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Oven Settings")
|
|
||||||
int32 CurrentPlayerScore{0};
|
|
||||||
|
|
||||||
private:
|
|
||||||
// An array of all the cookstoves, from left to right on the screen
|
|
||||||
TArray<TObjectPtr<AActor>> CookstoveObjects;
|
|
||||||
TArray<FCookstove> Cookstoves;
|
|
||||||
|
|
||||||
// ReSharper disable once CppUE4ProbableMemoryIssuesWithUObject
|
|
||||||
TObjectPtr<UDataTable> RecipesDataTable;
|
|
||||||
};
|
|
||||||
|
|
@ -7,10 +7,7 @@
|
||||||
{
|
{
|
||||||
"Name": "minicook",
|
"Name": "minicook",
|
||||||
"Type": "Runtime",
|
"Type": "Runtime",
|
||||||
"LoadingPhase": "Default",
|
"LoadingPhase": "Default"
|
||||||
"AdditionalDependencies": [
|
|
||||||
"Engine"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Plugins": [
|
"Plugins": [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue