#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() : 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(Subsystem->GetDefinition()) : nullptr; } TSharedRef UWorldMapWidget::RebuildWidget() { const UWorld* World = GetWorld(); UWorldMapSubsystem* Subsystem = World ? World->GetSubsystem() : 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 UWorldMapWidget::GetLayerIds() const { const UWorldMapDefinition* Resolved = GetResolvedDefinition(); return Resolved ? Resolved->GetLayerIds() : TArray(); } 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(MapWidget->GetMetresPerPixel()) : 0.f; } void UWorldMapWidget::SetMetresPerPixel(float InMetresPerPixel) { if (MapWidget.IsValid()) { MapWidget->SetMetresPerPixel(InMetresPerPixel); } } #undef LOCTEXT_NAMESPACE