215 lines
5.6 KiB
C++
215 lines
5.6 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "Merchant.h"
|
|
|
|
// Called when the game starts or when spawned
|
|
void AMerchant::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
timeManager = Cast<ATimeOfDayManager>(UGameplayStatics::GetActorOfClass(GetWorld(), ATimeOfDayManager::StaticClass()));
|
|
timeManager->OnDayPassed.AddDynamic(this, &AMerchant::ShiftDemands);
|
|
}
|
|
|
|
// Called every frame
|
|
void AMerchant::Tick(float DeltaTime)
|
|
{
|
|
Super::Tick(DeltaTime);
|
|
|
|
}
|
|
|
|
void AMerchant::AddItem(UItem* item, bool generateDemand)
|
|
{
|
|
FDemandDay newDemandDay;
|
|
|
|
if (generateDemand) {
|
|
int32 lastDayDemand = newDemandDay.GenerateRandomDemands30Days();
|
|
CurrentDayItemsDemands.FindOrAdd(item, lastDayDemand);
|
|
}
|
|
|
|
ItemsDemands.Add(item, newDemandDay);
|
|
}
|
|
|
|
void AMerchant::ChangeItemDemand(UItem* item, int32 amount)
|
|
{
|
|
if (CurrentDayItemsDemands.Contains(item)) {
|
|
CurrentDayItemsDemands[item] = amount;
|
|
}
|
|
}
|
|
|
|
void AMerchant::IncreaseItemDemand(UItem* item, int32 amount)
|
|
{
|
|
if (CurrentDayItemsDemands.Contains(item)) {
|
|
CurrentDayItemsDemands[item] += amount;
|
|
if (CurrentDayItemsDemands[item] > 200)
|
|
CurrentDayItemsDemands[item] = 200;
|
|
}
|
|
}
|
|
|
|
void AMerchant::DecreaseItemDemand(UItem* item, int32 amount)
|
|
{
|
|
if (CurrentDayItemsDemands.Contains(item)) {
|
|
CurrentDayItemsDemands[item] -= amount;
|
|
if (CurrentDayItemsDemands[item] < 0)
|
|
CurrentDayItemsDemands[item] = 0;
|
|
}
|
|
}
|
|
|
|
int32 AMerchant::GetDemandForItem(UItem* item)
|
|
{
|
|
int32* itemDemand = CurrentDayItemsDemands.Find(item);
|
|
|
|
if (itemDemand == nullptr || itemDemand == NULL)
|
|
return 100;
|
|
|
|
return *itemDemand;
|
|
}
|
|
|
|
TArray<int32> AMerchant::GetLast30DaysDemand(UItem* item)
|
|
{
|
|
FDemandDay* itemDemands = ItemsDemands.Find(item);
|
|
|
|
TArray<int32> defaultDemands;
|
|
if (itemDemands == nullptr || itemDemands == NULL) {
|
|
for (size_t i = 0; i < 30; i++)
|
|
{
|
|
defaultDemands.Add(100);
|
|
}
|
|
return defaultDemands;
|
|
}
|
|
FDemandDay defaultDemandsDay = (*itemDemands);
|
|
//Algo::Reverse(defaultDemandsDay.dayDemands);
|
|
|
|
return defaultDemandsDay.dayDemands;
|
|
}
|
|
|
|
void AMerchant::GetDemandForItemLastDay(UItem* item, int32& demand)
|
|
{
|
|
TMap<UItem*, int32> mapToReturn;
|
|
auto demandDay = ItemsDemands.Find(item);
|
|
if (demandDay == nullptr || demandDay == NULL) {
|
|
demand = 100;
|
|
}
|
|
else {
|
|
demand = demandDay->GetLastDayDemand();
|
|
}
|
|
}
|
|
|
|
int32 AMerchant::GetBuyCost(UItem* item)
|
|
{
|
|
int32* itemDemand = CurrentDayItemsDemands.Find(item);
|
|
|
|
if (itemDemand == nullptr || itemDemand == NULL) {
|
|
UE_LOG(LogTemp, Warning, TEXT("Buying cost for item not found!"));
|
|
return item->BaseCost;
|
|
}
|
|
int32 demand = *itemDemand;
|
|
float multiplier = ((float(demand) - 100.0f) / 200.0f) + 1.0f;
|
|
return item->BaseCost * multiplier;
|
|
}
|
|
|
|
int32 AMerchant::GetSellCost(UItem* item)
|
|
{
|
|
int32 buyCost = GetBuyCost(item);
|
|
const float multiplier = 0.8f;
|
|
|
|
return buyCost * multiplier;
|
|
}
|
|
|
|
int32 AMerchant::CalculateCostForDemand(UItem* item, int32 demand)
|
|
{
|
|
float modifiedMultiplier = ((demand - 100.0f) / 200.0f) + 1.0f;
|
|
float priceCorrection = float(item->BaseCost) * modifiedMultiplier;
|
|
|
|
return FMath::RoundToInt(priceCorrection);
|
|
}
|
|
|
|
int32 AMerchant::CalculateCostForDemandPrice(int32 cost, int32 demand)
|
|
{
|
|
float modifiedMultiplier = ((demand - 100.0f) / 200.0f) + 1.0f;
|
|
float priceCorrection = float(cost) * modifiedMultiplier;
|
|
|
|
return FMath::RoundToInt(priceCorrection);
|
|
}
|
|
|
|
void AMerchant::ShiftDemands()
|
|
{
|
|
for (auto& itemDemand : ItemsDemands) {
|
|
for (int32 i = itemDemand.Value.dayDemands.Num() - 1; i > 0; i--) {
|
|
itemDemand.Value.dayDemands[i] = itemDemand.Value.dayDemands[i - 1];
|
|
}
|
|
itemDemand.Value.dayDemands[0] = CurrentDayItemsDemands[itemDemand.Key];
|
|
|
|
int32 firstDayLower = itemDemand.Value.dayDemands[0] - 50;
|
|
if (firstDayLower < 0)
|
|
firstDayLower = 0;
|
|
|
|
int32 firstDayUpper = itemDemand.Value.dayDemands[0] + 50;
|
|
if (firstDayUpper > 200)
|
|
firstDayUpper = 200;
|
|
|
|
CurrentDayItemsDemands[itemDemand.Key] = FMath::RandRange(firstDayLower, firstDayUpper);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Picks 3 most in demand items, excluding seeds and returns them
|
|
/// </summary>
|
|
/// <returns>An array of items which are in demand</returns>
|
|
TArray<UItem*> AMerchant::PickMostInDemandItems()
|
|
{
|
|
TArray<int32> indexesToIgnore;
|
|
TArray<UItem*> keys;
|
|
ItemsDemands.GenerateKeyArray(keys);
|
|
|
|
if (ItemsMostDemands.Num() == 0) {
|
|
for (size_t i = 0; i < 3; i++)
|
|
{
|
|
ItemsMostDemands.Add(keys[0]);
|
|
}
|
|
}
|
|
|
|
for (int32 i = 0; i < 3; i++)
|
|
{
|
|
int32 highestDemand = 0;
|
|
int32 highestDemandIndex = 0;
|
|
for (int32 j = 0; j < keys.Num(); j++) {
|
|
if (indexesToIgnore.Contains(j) || keys[j]->Category == Category::Seed)
|
|
continue;
|
|
if (ItemsDemands[keys[j]].GetLastDayDemand() >= highestDemand) {
|
|
highestDemand = ItemsDemands[keys[j]].GetLastDayDemand();
|
|
highestDemandIndex = j;
|
|
}
|
|
}
|
|
indexesToIgnore.Add(highestDemandIndex);
|
|
ItemsMostDemands[i] = (keys[highestDemandIndex]);
|
|
}
|
|
|
|
return ItemsMostDemands;
|
|
}
|
|
|
|
float AMerchant::GetPriceChangeFromLastDay(UItem* item)
|
|
{
|
|
int32 currentDemand = 100;
|
|
int32 lastDayDemand = 100;
|
|
auto currentDemandPtr = CurrentDayItemsDemands.Find(item);
|
|
auto lastDayMemandPtr = ItemsDemands.Find(item);
|
|
|
|
if (currentDemandPtr != nullptr)
|
|
currentDemand = *currentDemandPtr;
|
|
|
|
if (lastDayMemandPtr != nullptr)
|
|
lastDayDemand = (*lastDayMemandPtr).GetLastDayDemand();
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("Current demand %d"), currentDemand);
|
|
UE_LOG(LogTemp, Warning, TEXT("Last day demand %d"), lastDayDemand);
|
|
int32 currentCost = CalculateCostForDemand(item, currentDemand);
|
|
int32 lastDayCost = CalculateCostForDemand(item, lastDayDemand);
|
|
UE_LOG(LogTemp, Warning, TEXT("Current cost %d"), currentCost);
|
|
UE_LOG(LogTemp, Warning, TEXT("Last day cost %d"), lastDayCost);
|
|
|
|
return (((float)currentCost - (float)lastDayCost) / (float)lastDayCost) * 100.0f;
|
|
}
|