LifePlay-Revival/Source/LifePlay/LPCityWaterSubsystem.h

180 lines
7.8 KiB
C
Raw Normal View History

// Lot STM1 (STM1-SPEC-03 § 2.6, pilote O-B) : pose en jeu du maillage d'eau d'une ville.
//
// Les cartes StreetMap n'ont pas d'eau (STM1-CART-03) ; en mode carte par defaut, le sol de pave de MapMarkers recouvre les
// fleuves. Ce sous-systeme pose /Game/Heavy/StreetMap/Water/<Ville> (cree par le commandlet LPBuildCityWater) sur l'acteur
// de la carte, 2 cm au-dessus du plan de pave (composant Plane de MapMarkers, Z lu en jeu) ; visible aussi en mode classique.
// Lecture seule du GameInstance par reflexion (GI.StreetMapStatic) : aucun Blueprint ni GI modifie. Ville sans asset d'eau :
// composant masque. Une ligne [LPCity] (LogLPCity) a chaque pose. Present aussi en Shipping (rendu du jeu).
// STM1-SPEC-08 (O2, option D) : masque aussi, a l'echelle 0, les maisons generiques (House*, Skyscraper*) de MapMarkers
// posees aux centres de /Game/Heavy/StreetMap/Water/<Ville>_Mask ; arbres et jeeps non touches ; indices conserves.
#pragma once
#include "CoreMinimal.h"
#include "Containers/Ticker.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "LPCityWaterSubsystem.generated.h"
class AActor;
class UHierarchicalInstancedStaticMeshComponent;
class UMaterialInterface;
class USceneComponent;
class ULPCityHouses;
class ULPCityLandmarks;
class ULPCityWaterMask;
class UStaticMeshComponent;
UCLASS()
class LIFEPLAY_API ULPCityWaterSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
private:
bool Tick(float DeltaTime);
/** Pose ou masque l'eau pour le maillage de carte courant. */
void UpdateWater(AActor* Street, UStaticMeshComponent* MapComp);
/** Z monde du plan de pave de MapMarkers ; false si introuvable (acteur pas encore cree). */
bool FindPlaneZ(const UWorld* World, double& OutZ) const;
/** STM1-SPEC-08 (O2) : charge le masque <Ville>_Mask de la carte courante (ou le vide). */
void LoadMask(const FString& City);
/** STM1-SPEC-08 (O2) : masque (echelle 0) les maisons generiques de MapMarkers posees aux centres du masque. */
void HideHousesInWater(UStaticMeshComponent* MapComp, bool bForce);
/** STM1-SPEC-10 (G3) : vrai si le point (repere de la carte, cm) tombe dans un polygone d'eau du masque. */
bool IsInWater(const FVector2D& Point) const;
/** STM1-SPEC-11 (M2) : pose les monuments <Ville> (pack ou base) sur la carte, retire ceux de la carte precedente. */
void UpdateLandmarks(AActor* Street, UStaticMeshComponent* MapComp, const FString& City);
/** STM1-SPEC-12 (G4-b) : pose les maisons de la table <Ville> (pack ou base), retire celles de la carte precedente. */
void UpdateHouses(AActor* Street, UStaticMeshComponent* MapComp, const FString& City);
/** STM1-SPEC-12 (G4-b) : maisons du pack visibles seulement hors mode classique (comme celles de MapMarkers).
* 1.3.0 : la carte classique en 3D, a l'inverse, n'est visible qu'en mode classique. */
void SyncHousesVisibility();
/** 1.3.0 (STM1-SPEC-14) : pose la carte classique en 3D <Ville> (batiments extrudes seuls, pack ou base) si elle existe. */
void UpdateClassic(AActor* Street, UStaticMeshComponent* MapComp, const FString& City);
/** 1.4.0 (STM1-SPEC-17) : sol de la ville (pack seulement) : instance de materiau Ground/<Ville> (chaussee, paves) et
* trottoirs Sidewalks/<Ville>, poses sous la carte et caches en mode classique. Retire ceux de la carte precedente. */
void UpdateGround(AActor* Street, UStaticMeshComponent* MapComp, const FString& City);
/** 1.4.0 : le BP StreetMap_Static impose StreetMapMasked (mode normal) ou StreetMapClassic (mode classique) sur la carte.
* A chaque image, apres le BP : en mode normal (et lp.City.Ground 1), le materiau du sol remplace StreetMapMasked ; en
* mode classique, rien (le materiau du jeu reste). */
void ApplyGround(UStaticMeshComponent* MapComp);
/** COMMUN-28 (STM1-SPEC-15, option b) : villes de pack seulement, icones de MapMarkers (WidgetComponents) filtrees selon la
* camera : sous lp.City.IconLowAltitudeM, celles a moins de lp.City.IconNearM ; au-dessus, une par case de
* lp.City.IconCellM. Recalcul quand la camera bouge ou que le nombre d'icones change. */
void UpdateIcons(UStaticMeshComponent* MapComp, bool bPackCity);
/** Rend visibles les icones que le filtre a cachees (et seulement celles-la). */
void RestoreIcons();
/** COMMUN-29 (S3) : filtre applique apres le tick des acteurs, a chaque image, dans l'image meme ou MapMarkers cree ou
* recycle ses icones (le ticker du sous-systeme ne passe que toutes les 0,25 s : d'ou le clignotement de COMMUN-28). */
void OnPostActorTick(UWorld* World, ELevelTick TickType, float DeltaSeconds);
FDelegateHandle PostActorTickHandle;
TWeakObjectPtr<UStaticMeshComponent> IconMapComp;
bool bIconPackCity = false;
/** Dernier mode applique (hysteresis de l'altitude). */
bool bLastIconLow = false;
FTSTicker::FDelegateHandle TickHandle;
/** Maillage de carte deja traite (chemin), pour ne poser qu'au changement. */
FString LastMapMesh;
/** Pose faite avec le repli de hauteur : a corriger des que le plan de MapMarkers apparait. */
bool bUsedFallbackZ = false;
/** Secondes passees a attendre le plan avant le repli. */
double WaitPlaneSeconds = 0.0;
UPROPERTY(Transient)
TObjectPtr<UStaticMeshComponent> WaterComponent;
/** Masque de la carte courante (nul si la ville n'en a pas). */
UPROPERTY(Transient)
TObjectPtr<ULPCityWaterMask> Mask;
/** Centres du masque ranges par case de 1 m (indice dans Mask->Centers). */
TMultiMap<FIntPoint, int32> MaskCells;
/** Nombre total d'instances de maisons a la derniere passe (nouvelle passe s'il change). */
int32 LastHouseInstances = -1;
/** STM1-SPEC-10 (G3) : boite de chaque anneau d'eau du masque ; anneaux exterieurs ranges par case de 100 m. */
TArray<FBox2D> WaterRingBoxes;
TMultiMap<FIntPoint, int32> WaterOuterCells;
/** Nombre total d'instances d'arbres a la derniere passe (nouvelle passe s'il change). */
int32 LastTreeInstances = -1;
/** STM1-SPEC-10 (C1) : acteur MapMarkers de la derniere passe (nouvelle passe s'il change). */
TWeakObjectPtr<AActor> LastMarkers;
/** STM1-SPEC-11 (M2) : monuments de la carte courante, leurs composants, et centres des maisons a masquer. */
UPROPERTY(Transient)
TObjectPtr<ULPCityLandmarks> Landmarks;
UPROPERTY(Transient)
TArray<TObjectPtr<UStaticMeshComponent>> LandmarkComponents;
TArray<FVector2D> LandmarkHideCenters;
TMultiMap<FIntPoint, int32> LandmarkCells;
FString LastLandmarkReport;
/** STM1-SPEC-12 (G4-b) : table de pose de la carte courante et un HISM par variante. */
UPROPERTY(Transient)
TObjectPtr<ULPCityHouses> HouseTable;
UPROPERTY(Transient)
TArray<TObjectPtr<UHierarchicalInstancedStaticMeshComponent>> HouseComponents;
/** COMMUN-28 : icones cachees par le filtre (celles que MapMarkers cache lui-meme ne sont jamais touchees). */
TSet<TWeakObjectPtr<USceneComponent>> IconsHiddenByFilter;
TWeakObjectPtr<AActor> LastIconMarkers;
FVector LastIconCamera = FVector(TNumericLimits<double>::Max());
FVector LastIconViewPoint = FVector(TNumericLimits<double>::Max());
int32 LastIconCount = -1;
FString LastIconsReport;
/** 1.3.0 : carte classique en 3D de la carte courante (nul si la ville n'en a pas). */
UPROPERTY(Transient)
TObjectPtr<UStaticMeshComponent> ClassicComponent;
/** 1.4.0 : materiau du sol de la ville courante (nul si son pack n'en a pas), materiau du jeu qu'il remplace, trottoirs. */
UPROPERTY(Transient)
TObjectPtr<UMaterialInterface> GroundMaterial;
UPROPERTY(Transient)
TObjectPtr<UMaterialInterface> GroundReplaced;
UPROPERTY(Transient)
TObjectPtr<UStaticMeshComponent> SidewalkComponent;
FString GroundCity;
int32 LastGroundState = -2;
int32 GroundReapplied = 0;
/** Dernier etat ClassicMap applique aux maisons du pack (-2 : jamais). */
int32 LastHousesClassic = -2;
FString LastHousesReport;
/** Dernier temoin ecrit (pour n'ecrire qu'au changement). */
FString LastMaskReport;
};