Improvements to watering and some stat forge fixes
This commit is contained in:
@@ -357,6 +357,68 @@ void ASeedBedActor::WaterAllSeedSlots()
|
||||
WaterSeedInSlot(SlotCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
int32 ASeedBedActor::GatherSlotsInRadius(const FVector& WorldLocation, float Radius, TArray<FIntVector2>& OutSlotCoordinates) const
|
||||
{
|
||||
OutSlotCoordinates.Reset();
|
||||
|
||||
// A radius of zero only ever covers the point itself, so there is nothing to gather
|
||||
if (Radius <= 0.f)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float RadiusSquared = FMath::Square(Radius);
|
||||
|
||||
for (const TPair<FIntVector2, FSeedBedSeedSlot>& SlotPair : SeedBedSeedSlotsMap)
|
||||
{
|
||||
// Only living plants are watered, an empty or dead slot has nothing to soak up
|
||||
if (!SlotHasLivingPlant(SlotPair.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FVector SlotWorldLocation;
|
||||
if (!GetSlotWorldLocation(SlotPair.Key, SlotWorldLocation))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only the plane of the bed counts, so watering from above or from uphill reaches the same slots
|
||||
if (FVector::DistSquaredXY(WorldLocation, SlotWorldLocation) > RadiusSquared)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OutSlotCoordinates.Add(SlotPair.Key);
|
||||
}
|
||||
|
||||
return OutSlotCoordinates.Num();
|
||||
}
|
||||
|
||||
int32 ASeedBedActor::WaterSlotsInRadius(const FVector& WorldLocation, float Radius)
|
||||
{
|
||||
// The slots are gathered first, a listener of the refresh is free to change the map while we water
|
||||
TArray<FIntVector2> SlotCoordinates;
|
||||
const int32 WateredSlotCount = GatherSlotsInRadius(WorldLocation, Radius, SlotCoordinates);
|
||||
|
||||
for (const FIntVector2& SlotCoordinate : SlotCoordinates)
|
||||
{
|
||||
WaterSeedInSlot(SlotCoordinate);
|
||||
}
|
||||
|
||||
// The cache is what the game state falls back to once the bed is streamed out, so it has to know
|
||||
// about the watering right away. Nothing was watered, so there is nothing to cache either.
|
||||
if (WateredSlotCount > 0)
|
||||
{
|
||||
if (AEleriGameState* GameState = Cast<AEleriGameState>(UGameplayStatics::GetGameState(this)))
|
||||
{
|
||||
GameState->CacheSeedData(SeedBedIndex, PrepareSeedSaveData());
|
||||
}
|
||||
}
|
||||
|
||||
return WateredSlotCount;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// GRID GENERATION
|
||||
//------------------------------------------------------------------------------------------------
|
||||
@@ -623,7 +685,12 @@ void ASeedBedActor::HighlightSlot(FIntVector2 SlotCoordinate)
|
||||
|
||||
void ASeedBedActor::StopHighlightingSlot()
|
||||
{
|
||||
HighlightDecal->SetVisibility(false);
|
||||
// The decal only exists once BeginPlay created it, a highlight is stopped on beds that never got one as well
|
||||
if (IsValid(HighlightDecal))
|
||||
{
|
||||
HighlightDecal->SetVisibility(false);
|
||||
}
|
||||
|
||||
HighlightedSlotIndex = FIntVector2::NoneValue;
|
||||
}
|
||||
|
||||
@@ -650,6 +717,14 @@ int32 ASeedBedActor::GetFreeSlotCount() const
|
||||
return FreeSlotCount;
|
||||
}
|
||||
bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const
|
||||
{
|
||||
float DistanceSquared = 0.f;
|
||||
|
||||
// The distance of the slot is only interesting for the planting highlight, the plain lookup ignores it
|
||||
return FindClosestFreeSlotWithDistance(WorldLocation, OutSlotCoordinate, DistanceSquared);
|
||||
}
|
||||
|
||||
bool ASeedBedActor::FindClosestFreeSlotWithDistance(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate, float& OutDistanceSquared) const
|
||||
{
|
||||
bool bFoundSlot = false;
|
||||
float ClosestDistanceSquared = 0.f;
|
||||
@@ -667,7 +742,8 @@ bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector
|
||||
continue;
|
||||
}
|
||||
|
||||
const float DistanceSquared = FVector::DistSquared(WorldLocation, SlotWorldLocation);
|
||||
// Only the plane of the bed counts, a player standing uphill has to reach the slot just as well
|
||||
const float DistanceSquared = FVector::DistSquaredXY(WorldLocation, SlotWorldLocation);
|
||||
if (!bFoundSlot || DistanceSquared < ClosestDistanceSquared)
|
||||
{
|
||||
bFoundSlot = true;
|
||||
@@ -676,6 +752,8 @@ bool ASeedBedActor::FindClosestFreeSlot(const FVector& WorldLocation, FIntVector
|
||||
}
|
||||
}
|
||||
|
||||
OutDistanceSquared = ClosestDistanceSquared;
|
||||
|
||||
return bFoundSlot;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,10 +196,24 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||
void WaterAllSeedSlots();
|
||||
|
||||
/** Waters every planted slot whose world location lies within the given radius around a world point.
|
||||
* Returns the number of slots that were watered and caches the new slot data into the game state. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||
int32 WaterSlotsInRadius(const FVector& WorldLocation, float Radius);
|
||||
|
||||
/** Collects the coordinates of every planted slot whose world location lies within the given radius.
|
||||
* Returns the number of collected slots, OutSlotCoordinates is emptied first. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||
int32 GatherSlotsInRadius(const FVector& WorldLocation, float Radius, TArray<FIntVector2>& OutSlotCoordinates) const;
|
||||
|
||||
/** Finds the free slot that is closest to the given world location */
|
||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||
bool FindClosestFreeSlot(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate) const;
|
||||
|
||||
/** Same as FindClosestFreeSlot, but also reports how far away the slot is, as a squared distance in XY */
|
||||
UFUNCTION(BlueprintCallable, Category = "Seed Bed")
|
||||
bool FindClosestFreeSlotWithDistance(const FVector& WorldLocation, FIntVector2& OutSlotCoordinate, float& OutDistanceSquared) const;
|
||||
|
||||
/** World location a plant of the given slot is placed at */
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Seed Bed")
|
||||
bool GetSlotWorldLocation(FIntVector2 SlotCoordinate, FVector& OutWorldLocation) const;
|
||||
|
||||
Reference in New Issue
Block a user