#include "IronsGame.h" #include "IronsPerformanceOverlay.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "InputAction.h" #include "InputMappingContext.h" #include "Engine/LocalPlayer.h" #include "GameFramework/CharacterMovementComponent.h" #include "Kismet/GameplayStatics.h" #include "Blueprint/WidgetBlueprintLibrary.h" #include "Engine/Engine.h" #include "Engine/GameViewportClient.h" #include "Widgets/SWindow.h" AIronsController::AIronsController(){PrimaryActorTick.bCanEverTick=true;} UIronsGameInstance* AIronsController::Host()const{return Cast(GetGameInstance());} AIronsCharacter* AIronsController::Mech()const{return Cast(GetPawn());} void AIronsController::BeginPlay(){ Super::BeginPlay();RebuildInput();UClass* Class=LoadClass(nullptr,TEXT("/Game/IRONSPORE/UI/WBP_IronsRoot.WBP_IronsRoot_C"));if(!Class)Class=UIronsScreen::StaticClass();Screen=CreateWidget(this,Class);Screen->AddToViewport(10);SetPage(GetWorld()->GetMapName().Contains(TEXT("L_Hangar"))?TEXT("home"):TEXT("play")); PerformanceOverlay=CreateWidget(this);PerformanceOverlay->AddToViewport(30); if(GEngine&&GEngine->GameViewport)if(auto Window=GEngine->GameViewport->GetWindow())Window->ShowWindow(); } void AIronsController::EndPlay(const EEndPlayReason::Type Reason){ if(PerformanceOverlay)PerformanceOverlay->RemoveFromParent();if(Screen)Screen->RemoveFromParent();Super::EndPlay(Reason); } void AIronsController::RebuildInput(){ auto H=Host();auto Local=GetLocalPlayer();auto Sub=Local?Local->GetSubsystem():nullptr;if(!H||!Sub)return; if(Context)Sub->RemoveMappingContext(Context);Context=NewObject(this);Actions.Empty(); auto E=Cast(InputComponent);if(E)E->ClearActionValueBindings(); for(int I=0;IKeys.Num();I++){auto A=NewObject(this);A->ValueType=EInputActionValueType::Boolean;Context->MapKey(A,FKey(*H->Keys[I]));Actions.Add(A);if(E)E->BindActionValue(A);} Sub->AddMappingContext(Context,0); } void AIronsController::SetPage(const FString& NewPage){ if(Page!=NewPage)PreviousPage=Page;Page=NewPage;bTrigger=false;bPodHeld=false;if(auto H=Host())H->Combat.freshTrigger=true; bool Play=Playing();bShowMouseCursor=!Play;ResetIgnoreLookInput();ResetIgnoreMoveInput();SetIgnoreLookInput(!Play);SetIgnoreMoveInput(!Play); if(Mech()){Mech()->GetCharacterMovement()->SetComponentTickEnabled(Play);if(!Play)Mech()->GetCharacterMovement()->StopMovementImmediately();} if(Play){FInputModeGameOnly Mode;SetInputMode(Mode);}else{FInputModeGameAndUI Mode;Mode.SetHideCursorDuringCapture(false);Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);if(Screen)Mode.SetWidgetToFocus(Screen->TakeWidget());SetInputMode(Mode);} if(Screen)Screen->ClearSelection(); } void AIronsController::Launch(bool Training){ auto H=Host();if(!H||!H->bReady)return;if(Training)H->EnterTraining();else if(H->IsTraining())H->LeaveTraining(); if(!H->IsTraining()&&!H->BeginSortie())return; UGameplayStatics::OpenLevel(this,Training?TEXT("/Game/IRONSPORE/Maps/L_TrainingRange"):TEXT("/Game/IRONSPORE/Maps/L_Warzone")); } void AIronsController::ReturnHome(){if(auto H=Host()){if(H->IsTraining())H->LeaveTraining();else if(H->Core().state().run.active)H->Accept(H->Core().save());}UGameplayStatics::OpenLevel(this,TEXT("/Game/IRONSPORE/Maps/L_Hangar"));} void AIronsController::Menu(){if(Playing())SetPage(TEXT("pause"));else if(Mech())SetPage(TEXT("play"));else SetPage(TEXT("home"));} void AIronsController::Interact(){if(Playing())if(auto M=GetWorld()->GetAuthGameMode())M->Interact();} void AIronsController::FirePressed(){if(Playing()){bTrigger=true;if(Mech())Mech()->Shoot();}} void AIronsController::FireReleased(){bTrigger=false;} void AIronsController::ProcessKey(FKey Key,bool Pressed){ auto H=Host();if(!H)return; if(Rebind>=0&&Pressed){if(Key==EKeys::Escape){Rebind=-1;return;}if(Key.IsGamepadKey())return; FString Name=Key.GetFName().ToString();for(int I=0;IKeys.Num();I++)if(I!=Rebind&&H->Keys[I]==Name){H->Notice(TEXT("ue.keyConflict"));return;}H->Keys[Rebind]=Name;Rebind=-1;H->SavePreferences();RebuildInput();return;} if(Key==EKeys::Escape&&Pressed){Menu();return;} if(!Playing())return; if(Key==FKey(*H->Keys[13])){if(Pressed)FirePressed();else FireReleased();return;} if(Key==FKey(*H->Keys[14])){if(Mech())Mech()->bAim=Pressed;return;} int Index=H->Keys.IndexOfByKey(Key.GetFName().ToString());if(Index<0)return; if(Index==11){bPodHeld=Pressed;return;}if(Index==4&&!Pressed){if(Mech())Mech()->StopJumping();return;}if(!Pressed)return; if(Index==4){if(Mech())Mech()->Jump();} else if(Index==5)H->Core().boost(H->Combat); else if(Index==6)H->Core().guard(H->Combat); else if(Index==7)H->Core().reload(H->Combat); else if(Index==8){if(Mech())Mech()->SwitchView();} else if(Index==9)Interact(); else if(Index==10)SetPage(TEXT("inventory")); else if(Index==12){if(Mech())Mech()->Shoot(true);} } bool AIronsController::InputKey(const FInputKeyEventArgs& Params){if(Params.Event==IE_Pressed||Params.Event==IE_Released)ProcessKey(Params.Key,Params.Event==IE_Pressed);return Super::InputKey(Params);} void AIronsController::PlayerTick(float Dt){ Super::PlayerTick(Dt);TickAcceptance(Dt);auto H=Host();auto P=Mech();if(!H||!H->bReady||!Playing()||!P)return; auto& S=H->Core();S.tick(Dt,H->Combat,!IsInputKeyDown(FKey(*H->Keys[13]))); auto E=Cast(InputComponent);auto Down=[&](int I){return E&&Actions.IsValidIndex(I)?E->GetBoundActionValue(Actions[I]).Get():IsInputKeyDown(FKey(*H->Keys[I]));}; FRotator Yaw(0,GetControlRotation().Yaw,0);FVector Forward=Yaw.Vector(),Right=FRotationMatrix(Yaw).GetUnitAxis(EAxis::Y); P->AddMovementInput(Forward,(Down(0)?1.f:0.f)-(Down(1)?1.f:0.f));P->AddMovementInput(Right,(Down(3)?1.f:0.f)-(Down(2)?1.f:0.f)); float X=0,Y=0;GetInputMouseDelta(X,Y);float MouseScale=H->Sensitivity*(P->bAim?H->AimSensitivity:1);AddYawInput(X*MouseScale);AddPitchInput(Y*MouseScale*(H->bInvertY?1:-1)); if(bTrigger)P->Shoot(); static float SaveClock=0;SaveClock+=Dt;if(SaveClock>30){SaveClock=0;H->Accept(S.save());} } void AIronsController::IronsUi(const FString& NewPage){ #if !UE_BUILD_SHIPPING if(FParse::Param(FCommandLine::Get(),TEXT("IronsporeQA")))SetPage(NewPage); #endif } void AIronsController::IronsQA(const FString& Command){ #if !UE_BUILD_SHIPPING if(!FParse::Param(FCommandLine::Get(),TEXT("IronsporeQA")))return; auto H=Host();if(!H)return;if(Command==TEXT("stock"))H->Accept(H->Core().seedAcceptanceStock()); else if(Command==TEXT("return")){if(H->FinishSortie(false))ReturnHome();} else if(Command==TEXT("destroy")){if(H->FinishSortie(true))ReturnHome();} else if(Command==TEXT("loot"))H->Accept(H->Core().addLoot("alloy",4,"qa-crate")); #endif }