// 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(VisibleAnywhere, BlueprintReadOnly, Category = "Agrarian|Weather") FAgrarianWeatherProviderSnapshot LastSnapshot; 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 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); bool ParseOpenMeteoForecast(const FString& ResponseContent, FName TileId, float Latitude, float Longitude, FAgrarianWeatherProviderSnapshot& OutSnapshot) const; };