// Copyright Epic Games, Inc. All Rights Reserved. #include "AgrarianGamePlayerController.h" #include "AgrarianGameCharacter.h" #include "AgrarianInventoryComponent.h" #include "AgrarianPersistenceSubsystem.h" #include "AgrarianShelterActor.h" #include "AgrarianSurvivalComponent.h" #include "EnhancedInputSubsystems.h" #include "Engine/LocalPlayer.h" #include "InputMappingContext.h" #include "Blueprint/UserWidget.h" #include "AgrarianGame.h" #include "Widgets/Input/SVirtualJoystick.h" void AAgrarianGamePlayerController::BeginPlay() { Super::BeginPlay(); // only spawn touch controls on local player controllers if (ShouldUseTouchControls() && IsLocalPlayerController()) { // spawn the mobile controls widget MobileControlsWidget = CreateWidget(this, MobileControlsWidgetClass); if (MobileControlsWidget) { // add the controls to the player screen MobileControlsWidget->AddToPlayerScreen(0); } else { UE_LOG(LogAgrarianGame, Error, TEXT("Could not spawn mobile controls widget.")); } } } void AAgrarianGamePlayerController::SetupInputComponent() { Super::SetupInputComponent(); // only add IMCs for local player controllers if (IsLocalPlayerController()) { // Add Input Mapping Contexts if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem(GetLocalPlayer())) { for (UInputMappingContext* CurrentContext : DefaultMappingContexts) { Subsystem->AddMappingContext(CurrentContext, 0); } // only add these IMCs if we're not using mobile touch input if (!ShouldUseTouchControls()) { for (UInputMappingContext* CurrentContext : MobileExcludedMappingContexts) { Subsystem->AddMappingContext(CurrentContext, 0); } } } } } bool AAgrarianGamePlayerController::ShouldUseTouchControls() const { // are we on a mobile platform? Should we force touch? return SVirtualJoystick::ShouldDisplayTouchInterface() || bForceTouchControls; } void AAgrarianGamePlayerController::AgrarianGrantItem(FName ItemId, int32 Quantity) { if (ItemId == NAME_None || Quantity <= 0) { ClientMessage(TEXT("Usage: AgrarianGrantItem ")); return; } ServerAgrarianGrantItem(ItemId, Quantity); } void AAgrarianGamePlayerController::AgrarianSaveWorld() { ServerAgrarianSaveWorld(); } void AAgrarianGamePlayerController::AgrarianLoadWorld() { ServerAgrarianLoadWorld(); } void AAgrarianGamePlayerController::AgrarianSurvival() { const AAgrarianGameCharacter* AgrarianCharacter = GetPawn(); const UAgrarianSurvivalComponent* SurvivalComponent = AgrarianCharacter ? AgrarianCharacter->GetSurvivalComponent() : nullptr; if (!SurvivalComponent) { ClientMessage(TEXT("No Agrarian survival component found.")); return; } const FAgrarianSurvivalSnapshot& Survival = SurvivalComponent->Survival; ClientMessage(FString::Printf( TEXT("Health %.1f | Stamina %.1f | Hunger %.1f | Thirst %.1f | Temp %.1fC | Injury %.1f"), Survival.Health, Survival.Stamina, Survival.Hunger, Survival.Thirst, Survival.BodyTemperature, Survival.InjurySeverity)); } void AAgrarianGamePlayerController::AgrarianHeal() { ServerAgrarianHeal(); } void AAgrarianGamePlayerController::ServerAgrarianGrantItem_Implementation(FName ItemId, int32 Quantity) { AAgrarianGameCharacter* AgrarianCharacter = GetPawn(); UAgrarianInventoryComponent* InventoryComponent = AgrarianCharacter ? AgrarianCharacter->GetInventoryComponent() : nullptr; if (!InventoryComponent) { ClientMessage(TEXT("No Agrarian inventory component found.")); return; } FAgrarianItemStack Stack; Stack.ItemId = ItemId; Stack.DisplayName = FText::FromName(ItemId); Stack.Quantity = Quantity; if (InventoryComponent->AddItem(Stack)) { ClientMessage(FString::Printf(TEXT("Granted %d x %s."), Quantity, *ItemId.ToString())); } else { ClientMessage(FString::Printf(TEXT("Failed to grant %d x %s."), Quantity, *ItemId.ToString())); } } void AAgrarianGamePlayerController::ServerAgrarianSaveWorld_Implementation() { UAgrarianPersistenceSubsystem* Persistence = GetGameInstance() ? GetGameInstance()->GetSubsystem() : nullptr; if (!Persistence) { ClientMessage(TEXT("No Agrarian persistence subsystem found.")); return; } const bool bSaved = Persistence->SaveCurrentWorld(); ClientMessage(bSaved ? TEXT("Agrarian world saved.") : TEXT("Agrarian world save failed.")); } void AAgrarianGamePlayerController::ServerAgrarianLoadWorld_Implementation() { UAgrarianPersistenceSubsystem* Persistence = GetGameInstance() ? GetGameInstance()->GetSubsystem() : nullptr; if (!Persistence) { ClientMessage(TEXT("No Agrarian persistence subsystem found.")); return; } Persistence->RegisterWorldActorClass(TEXT("primitive_shelter"), AAgrarianShelterActor::StaticClass()); const UAgrarianSaveGame* SaveGame = Persistence->LoadOrCreateSave(); const int32 RestoredCount = Persistence->RestoreWorldActors(SaveGame); ClientMessage(FString::Printf(TEXT("Agrarian world loaded. Restored actors: %d."), RestoredCount)); } void AAgrarianGamePlayerController::ServerAgrarianHeal_Implementation() { AAgrarianGameCharacter* AgrarianCharacter = GetPawn(); UAgrarianSurvivalComponent* SurvivalComponent = AgrarianCharacter ? AgrarianCharacter->GetSurvivalComponent() : nullptr; if (!SurvivalComponent) { ClientMessage(TEXT("No Agrarian survival component found.")); return; } SurvivalComponent->RestoreHealth(100.0f); SurvivalComponent->AddFood(100.0f); SurvivalComponent->AddWater(100.0f); SurvivalComponent->AddWarmth(37.0f - SurvivalComponent->Survival.BodyTemperature); ClientMessage(TEXT("Agrarian survival restored.")); }