2026-10-20 15:35:10 +00:00
|
|
|
// 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;
|
2026-10-22 19:10:39 +00:00
|
|
|
class UHierarchicalInstancedStaticMeshComponent;
|
|
|
|
|
class UMaterialInterface;
|
|
|
|
|
class USceneComponent;
|
|
|
|
|
class ULPCityHouses;
|
|
|
|
|
class ULPCityLandmarks;
|
2026-10-20 15:35:10 +00:00
|
|
|
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);
|
|
|
|
|
|
2026-10-22 19:10:39 +00:00
|
|
|
/** 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;
|
|
|
|
|
|
2026-10-20 15:35:10 +00:00
|
|
|
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;
|
|
|
|
|
|
2026-10-22 19:10:39 +00:00
|
|
|
/** 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;
|
|
|
|
|
|
2026-10-20 15:35:10 +00:00
|
|
|
/** Dernier temoin ecrit (pour n'ecrire qu'au changement). */
|
|
|
|
|
FString LastMaskReport;
|
|
|
|
|
};
|