minicook/Source/minicook/OvenPawn.cpp

149 lines
No EOL
3.7 KiB
C++

// 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;
}