This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AgrarianGameArchive/Source/AgrarianGame/AgrarianWeatherProviderSubsystem.h
T
2026-05-15 23:25:00 -07:00

126 lines
5.0 KiB
C++

// Copyright Pacificao. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "HttpFwd.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "AgrarianTypes.h"
#include "AgrarianWeatherProviderSubsystem.generated.h"
class AAgrarianGameState;
class IHttpRequest;
class IHttpResponse;
USTRUCT(BlueprintType)
struct FAgrarianWeatherProviderSnapshot
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FName TileId = NAME_None;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float Latitude = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float Longitude = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FString Provider = TEXT("open-meteo");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FString ProviderTimestamp;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float CurrentTemperatureC = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float DailyLowTemperatureC = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float DailyHighTemperatureC = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float PrecipitationMm = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float WindSpeedKmh = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float CloudCoverPercent = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float RelativeHumidityPercent = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
float PressureMslHpa = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
int32 WeatherCode = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
EAgrarianWeatherType MappedWeather = EAgrarianWeatherType::Clear;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
bool bIsValid = false;
};
UCLASS()
class UAgrarianWeatherProviderSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
bool bEnableLiveWeatherRequests = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FString OpenMeteoForecastEndpoint = TEXT("https://api.open-meteo.com/v1/forecast");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
bool bEnableNoaaNwsFallbackForUSTiles = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FString NoaaNwsPointsEndpoint = TEXT("https://api.weather.gov/points");
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Weather")
FString NoaaNwsUserAgent = TEXT("AgrarianGameMVP/0.1");
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Weather")
FAgrarianWeatherProviderSnapshot LastSnapshot;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Weather")
FString LastNoaaNwsForecastGridDataUrl;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Weather")
bool RequestWeatherForActiveGameState();
UFUNCTION(BlueprintCallable, Category = "Agrarian|Weather")
bool RequestWeatherForTile(FName TileId, float Latitude, float Longitude);
UFUNCTION(BlueprintPure, Category = "Agrarian|Weather")
FString BuildOpenMeteoForecastUrl(FName TileId, float Latitude, float Longitude) const;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Weather")
bool RequestNoaaNwsFallbackForTile(FName TileId, float Latitude, float Longitude);
UFUNCTION(BlueprintPure, Category = "Agrarian|Weather")
bool IsNoaaNwsEligibleCoordinate(float Latitude, float Longitude) const;
UFUNCTION(BlueprintPure, Category = "Agrarian|Weather")
FString BuildNoaaNwsPointsUrl(float Latitude, float Longitude) const;
UFUNCTION(BlueprintCallable, Category = "Agrarian|Weather")
bool ApplySnapshotToGameState(const FAgrarianWeatherProviderSnapshot& Snapshot, AAgrarianGameState* GameState) const;
static EAgrarianWeatherType MapOpenMeteoWeatherCode(int32 WeatherCode, float PrecipitationMm, float WindSpeedKmh);
private:
void OnOpenMeteoResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, FName TileId, float Latitude, float Longitude);
void OnNoaaNwsPointsResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, FName TileId, float Latitude, float Longitude);
void OnNoaaNwsGridDataResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful, FName TileId, float Latitude, float Longitude);
bool ParseOpenMeteoForecast(const FString& ResponseContent, FName TileId, float Latitude, float Longitude, FAgrarianWeatherProviderSnapshot& OutSnapshot) const;
bool ParseNoaaNwsGridData(const FString& ResponseContent, FName TileId, float Latitude, float Longitude, FAgrarianWeatherProviderSnapshot& OutSnapshot) const;
};