Files
2026-09-25 17:02:24 +03:00

162 lines
3.9 KiB
C++

#include "UI/WorldMapWidget.h"
#include "Engine/World.h"
#include "UI/SWorldMap.h"
#include "Widgets/SNullWidget.h"
#include "World/WorldMapDefinition.h"
#include "World/WorldMapSubsystem.h"
#define LOCTEXT_NAMESPACE "SaltyWorldMap"
UWorldMapDefinition* UWorldMapWidget::GetResolvedDefinition() const
{
if (Definition)
{
return Definition;
}
const UWorld* World = GetWorld();
const UWorldMapSubsystem* Subsystem = World ? World->GetSubsystem<UWorldMapSubsystem>() : nullptr;
// const_cast because the subsystem hands out a const view of shared content and SWorldMap holds a strong
// pointer it cannot make const. Nothing here writes to the asset.
return Subsystem ? const_cast<UWorldMapDefinition*>(Subsystem->GetDefinition()) : nullptr;
}
TSharedRef<SWidget> UWorldMapWidget::RebuildWidget()
{
const UWorld* World = GetWorld();
UWorldMapSubsystem* Subsystem = World ? World->GetSubsystem<UWorldMapSubsystem>() : nullptr;
MapWidget = SNew(SWorldMap)
.Definition(GetResolvedDefinition())
.Layer(Layer)
.ShowGrid(bShowGrid)
.ShowScaleBar(bShowScaleBar)
.ShowMarkers(bShowMarkers)
.ShowLocalPlayer(bShowLocalPlayer)
.AllowInput(bAllowInput)
.MarkerSource(Subsystem)
.OnClicked(FOnWorldMapClicked::CreateUObject(this, &UWorldMapWidget::HandleClicked));
MapWidget->SetFollowLocalPlayer(bFollowLocalPlayer);
return MapWidget.ToSharedRef();
}
void UWorldMapWidget::SynchronizeProperties()
{
Super::SynchronizeProperties();
if (!MapWidget.IsValid())
{
return;
}
MapWidget->SetDefinition(GetResolvedDefinition());
MapWidget->SetLayer(Layer);
MapWidget->SetShowGrid(bShowGrid);
MapWidget->SetShowScaleBar(bShowScaleBar);
MapWidget->SetShowMarkers(bShowMarkers);
MapWidget->SetShowLocalPlayer(bShowLocalPlayer);
MapWidget->SetAllowInput(bAllowInput);
MapWidget->SetFollowLocalPlayer(bFollowLocalPlayer);
}
void UWorldMapWidget::ReleaseSlateResources(bool bReleaseChildren)
{
Super::ReleaseSlateResources(bReleaseChildren);
MapWidget.Reset();
}
#if WITH_EDITOR
const FText UWorldMapWidget::GetPaletteCategory()
{
return LOCTEXT("PaletteCategory", "Salty");
}
#endif
void UWorldMapWidget::HandleClicked(FVector2D WorldCm)
{
OnMapClicked.Broadcast(WorldCm);
}
void UWorldMapWidget::SetLayer(FName InLayer)
{
Layer = InLayer;
if (MapWidget.IsValid())
{
MapWidget->SetLayer(InLayer);
// Read it back: an id the definition does not have is ignored rather than obeyed, and the property
// should say what is on screen rather than what was asked for.
Layer = MapWidget->GetLayer();
}
}
void UWorldMapWidget::NextLayer()
{
if (MapWidget.IsValid())
{
MapWidget->NextLayer();
Layer = MapWidget->GetLayer();
}
}
FName UWorldMapWidget::GetLayer() const
{
return MapWidget.IsValid() ? MapWidget->GetLayer() : Layer;
}
TArray<FName> UWorldMapWidget::GetLayerIds() const
{
const UWorldMapDefinition* Resolved = GetResolvedDefinition();
return Resolved ? Resolved->GetLayerIds() : TArray<FName>();
}
void UWorldMapWidget::FocusOnWorldLocation(FVector WorldLocation)
{
if (MapWidget.IsValid())
{
MapWidget->SetFollowLocalPlayer(false);
MapWidget->FocusOnWorld(FVector2D(WorldLocation.X, WorldLocation.Y));
}
}
void UWorldMapWidget::ZoomToFit()
{
if (MapWidget.IsValid())
{
MapWidget->ZoomToFit();
}
}
void UWorldMapWidget::SetFollowLocalPlayer(bool bValue)
{
bFollowLocalPlayer = bValue;
if (MapWidget.IsValid())
{
MapWidget->SetFollowLocalPlayer(bValue);
}
}
bool UWorldMapWidget::FocusOnLocalPlayer()
{
if (!MapWidget.IsValid() || !MapWidget->FocusOnLocalPlayer())
{
return false;
}
// Mirror it back, so the property says what the widget is actually doing.
bFollowLocalPlayer = true;
return true;
}
float UWorldMapWidget::GetMetresPerPixel() const
{
return MapWidget.IsValid() ? static_cast<float>(MapWidget->GetMetresPerPixel()) : 0.f;
}
void UWorldMapWidget::SetMetresPerPixel(float InMetresPerPixel)
{
if (MapWidget.IsValid())
{
MapWidget->SetMetresPerPixel(InMetresPerPixel);
}
}
#undef LOCTEXT_NAMESPACE