Guest User

BaseGameMode.cpp

a guest
Oct 11th, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.46 KB | None | 0 0
  1. #include "FPSTemplate.h"
  2. #include "Game/BaseGameMode.h"
  3. #include "Player/BasePlayerController.h"
  4. #include "HUD/TeamSelectionHUD.h"
  5. #include "Player/BasePlayerState.h"
  6. #include "Game/BaseGameState.h"
  7. #include "BaseWorldSettings.h"
  8.  
  9. ABaseGameMode::ABaseGameMode(const FObjectInitializer & ObjectInitializer)
  10. {
  11.     LoadoutBuilderComponent = ObjectInitializer.CreateDefaultSubobject<ULoadoutBuilderComponent>(this, TEXT("LoadoutBuilderComponent"));
  12.  
  13.     static ConstructorHelpers::FObjectFinder<UClass> NewSoldierClass(TEXT("Blueprint'/Game/FPSTemplate/Soldier/BP_Soldier.BP_Soldier_C'"));
  14.     SoldierClass = NewSoldierClass.Object;
  15.  
  16.     DefaultPawnClass = NULL;
  17.     SpectatorClass = NULL;
  18.     PlayerControllerClass = ABasePlayerController::StaticClass();
  19.     PlayerStateClass = ABasePlayerState::StaticClass();
  20.     GameStateClass = ABaseGameState::StaticClass();
  21.  
  22.     MinRespawnDelay = 5.f;
  23.  
  24.     bUseCustomLoadout = true;
  25.     TeamMode = ETeamModeEnum::MultipleTeams;
  26. }
  27.  
  28. void ABaseGameMode::InitGameState()
  29. {
  30.     Super::InitGameState();
  31.  
  32.     ABaseGameState * BaseGameState = Cast<ABaseGameState>(GameState);
  33.     if (BaseGameState)
  34.     {
  35.         // Max length of match
  36.         BaseGameState->TimeRemaining = 3600;
  37.     }
  38. }
  39.  
  40. void ABaseGameMode::PostLogin(APlayerController * NewPlayer)
  41. {
  42.     Super::PostLogin(NewPlayer);
  43.  
  44.     ABasePlayerController * PC = Cast<ABasePlayerController>(NewPlayer);
  45.     if (PC)
  46.     {
  47.         if (HasMatchEnded())
  48.         {
  49.             PC->EnterMatchEndState();
  50.         }
  51.         else
  52.         {
  53.             switch (TeamMode)
  54.             {
  55.             case (ETeamModeEnum::MultipleTeams) :
  56.                 PC->EnterTeamSelectionState();
  57.                 break;
  58.             case (ETeamModeEnum::OneTeam) :
  59.                 PC->SetTeam(ETeamEnum::TeamA);
  60.                 MovePlayerToEntryState(PC);
  61.                 break;
  62.             case (ETeamModeEnum::FreeForAll) :
  63.                 // Leave player in None team, which is used as a free for all team type
  64.                 MovePlayerToEntryState(PC);
  65.                 break;
  66.             }
  67.         }
  68.  
  69.         BroadcastChatMessage(PC, TEXT("Connected"), false);
  70.     }
  71. }
  72.  
  73. void ABaseGameMode::Logout(AController * Exiting)
  74. {
  75.     //ABasePlayerController * PC = Cast<ABasePlayerController>(Exiting);
  76.     if (Exiting)
  77.     {
  78.         ASoldier * Soldier = Cast<ASoldier>(Exiting->GetPawn());
  79.         if (Soldier)
  80.         {
  81.             Soldier->Destroy();
  82.         }
  83.     }
  84.  
  85.     Super::Logout(Exiting);
  86. }
  87.  
  88. void ABaseGameMode::Reset()
  89. {
  90.     // Do nothing
  91. }
  92.  
  93. void ABaseGameMode::MovePlayerToEntryState(ABasePlayerController * PC)
  94. {
  95.     PC->EnterSpawnState();
  96. }
  97.  
  98. void ABaseGameMode::OnTimeExpired()
  99. {
  100.     // By default no team wins when match time expires
  101.     EndMatch();
  102. }
  103.  
  104. void ABaseGameMode::EndMatch()
  105. {
  106.     Super::EndMatch();
  107.  
  108.     // Transition all players to match end state
  109.     MoveAllPlayersToState(EPlayerStateEnum::MatchEnd);
  110. }
  111.  
  112. void ABaseGameMode::EndMatch(ETeamEnum WinnerTeam)
  113. {
  114.     ABaseGameState * BaseGameState = Cast<ABaseGameState>(GameState);
  115.     if (BaseGameState)
  116.     {
  117.         BaseGameState->MatchWinner = WinnerTeam;
  118.     }
  119.  
  120.     EndMatch();
  121. }
  122.  
  123. void ABaseGameMode::EndMatch(ABasePlayerState * WinnerPS)
  124. {
  125.     ABaseGameState * BaseGameState = Cast<ABaseGameState>(GameState);
  126.     if (BaseGameState)
  127.     {
  128.         BaseGameState->WinnerPlayerState = WinnerPS;
  129.     }
  130.  
  131.     EndMatch();
  132. }
  133.  
  134. void ABaseGameMode::MoveAllPlayersToState(EPlayerStateEnum::Type NewState)
  135. {
  136.     // Save enter state function pointer so we don't have to do the switch for every player
  137.     typedef void (ABasePlayerController::*FunctionPtr)(void);
  138.     FunctionPtr Function = &ABasePlayerController::EnterSpectatingState;
  139.     switch (NewState)
  140.     {
  141.     case (EPlayerStateEnum::TeamSelection) :
  142.         Function = &ABasePlayerController::EnterTeamSelectionState;
  143.         break;
  144.     case (EPlayerStateEnum::Spawn) :
  145.         Function = &ABasePlayerController::EnterSpawnState;
  146.         break;
  147.     case (EPlayerStateEnum::Playing) :
  148.         Function = &ABasePlayerController::EnterPlayingState;
  149.         break;
  150.     case (EPlayerStateEnum::Death) :
  151.         Function = &ABasePlayerController::EnterDeathState;
  152.         break;
  153.     case (EPlayerStateEnum::Spectating) :
  154.         Function = &ABasePlayerController::EnterSpectatingState;
  155.         break;
  156.     case (EPlayerStateEnum::MatchEnd) :
  157.         Function = &ABasePlayerController::EnterMatchEndState;
  158.         break;
  159.     }
  160.  
  161.     for (FConstPlayerControllerIterator PlayerItr = GetWorld()->GetPlayerControllerIterator(); PlayerItr; ++PlayerItr)
  162.     {
  163.         ABasePlayerController * PC = Cast<ABasePlayerController>(*PlayerItr);
  164.         if (PC)
  165.         {
  166.             (PC->*Function)();
  167.         }
  168.     }
  169. }
  170.  
  171. void ABaseGameMode::CalcDamage(float & OutDamageAmount, ABasePlayerController * PC, ABasePlayerController * OtherPC)
  172. {
  173.     if (OtherPC && OtherPC != PC && !bFriendlyFire && !PC->IsEnemyFor(OtherPC))
  174.     {
  175.         OutDamageAmount = 0.f;
  176.     }
  177. }
  178.  
  179. void ABaseGameMode::OnSoldierDied(ASoldier * Soldier, const FDamageEvent & DamageEvent, ABasePlayerController * EventInstigator, AActor * DamageCauser)
  180. {
  181.     ABasePlayerState * PS = Cast<ABasePlayerState>(Soldier->PlayerState);
  182.     if (PS)
  183.     {
  184.         ABasePlayerState * OtherPS = Cast<ABasePlayerState>(EventInstigator != NULL ? EventInstigator->PlayerState : NULL);
  185.  
  186.         // Notify all players that a soldier was killed
  187.         for (FConstPlayerControllerIterator PlayerItr = GetWorld()->GetPlayerControllerIterator(); PlayerItr; ++PlayerItr)
  188.         {
  189.             ABasePlayerController * BasePlayer = Cast<ABasePlayerController>(*PlayerItr);
  190.             if (BasePlayer)
  191.             {
  192.                 BasePlayer->ClientOnPlayerDied(TSubclassOf<UBaseDamageType>(*DamageEvent.DamageTypeClass), PS, OtherPS);
  193.             }
  194.         }
  195.  
  196.         // Dead soldier player controller
  197.         ABasePlayerController * PC = Cast<ABasePlayerController>(Soldier->Controller);
  198.         if (PC)
  199.         {
  200.             OnPlayerDied(PC);
  201.  
  202.             if (EventInstigator)
  203.             {
  204.                 if (PS != OtherPS && PS->IsEnemyFor(OtherPS))
  205.                 {
  206.                     OnPlayerKilledEnemy(DamageEvent, EventInstigator, PC);
  207.                 }
  208.                 else
  209.                 {
  210.                     OnPlayerKilledTeammate(DamageEvent, EventInstigator, PC);
  211.                 }
  212.             }
  213.  
  214.             // Give kill assist points
  215.             for (const FDamageInfo & DamageInfo : Soldier->GetDamageInfoArray())
  216.             {
  217.                 if (DamageInfo.Instigator && DamageInfo.Instigator != EventInstigator && DamageInfo.Instigator->GetTeam() != PC->GetTeam())
  218.                 {
  219.                     ABasePlayerController * AssistPC = Cast<ABasePlayerController>(DamageInfo.Instigator);
  220.                     if (AssistPC)
  221.                     {
  222.                         AssistPC->AddScore(DamageInfo.DamageAmount);
  223.                         AssistPC->ClientOnAssistedKill(DamageInfo.DamageAmount);
  224.                     }
  225.                 }
  226.             }
  227.         }
  228.     }
  229.  
  230.     // Set life span of soldier to let it disappear
  231.     Soldier->SetLifeSpan(10.f);
  232. }
  233.  
  234. void ABaseGameMode::OnPlayerDied(ABasePlayerController * PC)
  235. {
  236.     PC->AddDeath();
  237.     PC->EnterDeathState();
  238. }
  239.  
  240. void ABaseGameMode::OnPlayerKilledEnemy(const FDamageEvent & DamageEvent, ABasePlayerController * PC, ABasePlayerController * OtherPC)
  241. {
  242.     PC->AddKill();
  243.     UBaseDamageType * DamageTypeCDO = Cast<UBaseDamageType>(DamageEvent.DamageTypeClass.GetDefaultObject());
  244.     PC->AddScore(DamageTypeCDO ? DamageTypeCDO->KillReward : 100);
  245. }
  246.  
  247. void ABaseGameMode::OnPlayerKilledTeammate(const FDamageEvent & DamageEvent, ABasePlayerController * PC, ABasePlayerController * OtherPC)
  248. {
  249.     // Could apply point penalty here
  250. }
  251.  
  252. int32 ABaseGameMode::GetNumPlayersInTeam(ETeamEnum Team) const
  253. {
  254.     ABaseGameState * GameState = GetGameState<ABaseGameState>();
  255.     if (GameState)
  256.     {
  257.         int32 Num = 0;
  258.         for (APlayerState * PS : GameState->PlayerArray)
  259.         {
  260.             ABasePlayerState * BasePS = Cast<ABasePlayerState>(PS);
  261.             if (BasePS && BasePS->GetTeam() == Team)
  262.             {
  263.                 Num++;
  264.             }
  265.         }
  266.  
  267.         return Num;
  268.     }
  269.  
  270.     return 0;
  271. }
  272.  
  273. void ABaseGameMode::PlayerJoinTeam(ABasePlayerController * PC, ETeamEnum InTeam)
  274. {
  275.     if (CanPlayerJoinTeam(PC, InTeam))
  276.     {
  277.         PC->SetTeam(InTeam);
  278.         MovePlayerToEntryState(PC);
  279.     }
  280. }
  281.  
  282. void ABaseGameMode::PlayerAutoJoinTeam(ABasePlayerController * PC)
  283. {
  284.     // Auto select team based on number of players
  285.     PlayerJoinTeam(PC, GetNumPlayersInTeam(ETeamEnum::TeamA) > GetNumPlayersInTeam(ETeamEnum::TeamB) ? ETeamEnum::TeamB : ETeamEnum::TeamA);
  286. }
  287.  
  288. bool ABaseGameMode::CanPlayerJoinTeam(ABasePlayerController * PC, ETeamEnum InTeam) const
  289. {
  290.     if (!PC || PC->GetState() == EPlayerStateEnum::Playing || TeamMode != ETeamModeEnum::MultipleTeams || HasMatchEnded()) return false;
  291.  
  292.     uint16 NumA = GetNumPlayersInTeam(ETeamEnum::TeamA);
  293.     uint16 NumB = GetNumPlayersInTeam(ETeamEnum::TeamB);
  294.  
  295.     // Remove PC from number of player controllers if already joined a team
  296.     switch (PC->GetTeam())
  297.     {
  298.     case (ETeamEnum::TeamA) :
  299.         NumA--;
  300.         break;
  301.     case (ETeamEnum::TeamB) :
  302.         NumB--;
  303.         break;
  304.     }
  305.  
  306.     if (InTeam == ETeamEnum::TeamA)
  307.     {
  308.         return NumA <= NumB + 1;
  309.     }
  310.     else
  311.     {
  312.         return NumB <= NumA + 1;
  313.     }
  314.  
  315.     return false;
  316. }
  317.  
  318. void ABaseGameMode::PlayerSpawn(ABasePlayerController * PC)
  319. {
  320.     if (CanPlayerSpawn(PC))
  321.     {
  322.         AActor * PlayerStart = ChoosePlayerStart(PC);
  323.         if (PlayerStart)
  324.         {
  325.             FActorSpawnParameters SpawnParams;
  326.             SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
  327.  
  328.             // Spawn soldier
  329.             ASoldier * Soldier = GetWorld()->SpawnActor<ASoldier>(SoldierClass, PlayerStart->GetActorLocation(), FRotator(0.f, PlayerStart->GetActorRotation().Yaw, 0.f), SpawnParams);
  330.             if (Soldier)
  331.             {
  332.                 USkeletalMesh * SoldierMesh = NULL;
  333.                 ABaseWorldSettings * WorldSettings = Cast<ABaseWorldSettings>(GetWorldSettings());
  334.                 if (WorldSettings)
  335.                 {
  336.                     const ETeamEnum PlayerTeam = PC->GetTeam();
  337.                     if (PlayerTeam == ETeamEnum::TeamA || PlayerTeam == ETeamEnum::None)
  338.                     {
  339.                         if (WorldSettings->TeamASoldierMeshes.Num() > 0)
  340.                         {
  341.                             SoldierMesh = WorldSettings->TeamASoldierMeshes[FMath::RandRange(0, WorldSettings->TeamASoldierMeshes.Num() - 1)];
  342.                         }
  343.                     }
  344.                     if (PlayerTeam == ETeamEnum::TeamB)
  345.                     {
  346.                         if (WorldSettings->TeamBSoldierMeshes.Num() > 0)
  347.                         {
  348.                             SoldierMesh = WorldSettings->TeamBSoldierMeshes[FMath::RandRange(0, WorldSettings->TeamBSoldierMeshes.Num() - 1)];
  349.                         }
  350.                     }
  351.                 }
  352.  
  353.                 Soldier->SetLoadout(GetPlayerLoadout(PC), SoldierMesh);
  354.                 PC->Possess(Soldier);
  355.                 PC->EnterPlayingState();
  356.             }
  357.         }
  358.     }
  359. }
  360.  
  361. bool ABaseGameMode::CanPlayerSpawn(ABasePlayerController * PC) const
  362. {
  363.     // Player can only spawn when match is still in progress
  364.     return PC != NULL && !HasMatchEnded();
  365. }
  366.  
  367. const FLoadoutStruct & ABaseGameMode::GetPlayerLoadout(ABasePlayerController * PC) const
  368. {
  369.     return bUseCustomLoadout ? PC->GetLoadout() : DefaultLoadout;
  370. }
  371.  
  372. void ABaseGameMode::PlayerSetLoadout(ABasePlayerController * PC, const FLoadoutStruct & Loadout)
  373. {
  374.     if (PC)
  375.     {
  376.         // Rebuild loadout to validate it and apply it to PC
  377.         LoadoutBuilderComponent->SetLoadoutChecked(Loadout);
  378.         PC->SetLoadout(LoadoutBuilderComponent->Loadout);
  379.     }
  380. }
  381.  
  382. bool ABaseGameMode::KickPlayer(ABasePlayerController * KickedPlayer, const FText & KickReason)
  383. {
  384.     if (GameSession)
  385.     {
  386.         return GameSession->KickPlayer(KickedPlayer, KickReason);
  387.     }
  388.  
  389.     return false;
  390. }
  391.  
  392. void ABaseGameMode::ServerTravel(const FString & MapName)
  393. {
  394.     GetWorld()->ServerTravel("/Game/FPSTemplate/Maps/" + MapName);
  395. }
  396.  
  397. void ABaseGameMode::BroadcastChatMessage(ABasePlayerController * FromPC, const FString & Message, bool bTeamOnly)
  398. {
  399.     ABasePlayerState * FromPS = Cast<ABasePlayerState>(FromPC->PlayerState);
  400.     for (FConstPlayerControllerIterator PlayerItr = GetWorld()->GetPlayerControllerIterator(); PlayerItr; ++PlayerItr)
  401.     {
  402.         ABasePlayerController * PC = Cast<ABasePlayerController>(*PlayerItr);
  403.         if (CanPlayerReceiveChatMessage(FromPC, PC, bTeamOnly))
  404.         {
  405.             PC->ClientReceiveChatMessage(Message, FromPS);
  406.         }
  407.     }
  408. }
  409.  
  410. bool ABaseGameMode::CanPlayerReceiveChatMessage(ABasePlayerController * FromPC, ABasePlayerController * ToPC, bool bTeamOnly)
  411. {
  412.     if (FromPC && ToPC)// && ToPC->GetState() != EPlayerStateEnum::TeamSelection)
  413.     {
  414.         return !bTeamOnly || FromPC->GetTeam() == ToPC->GetTeam();
  415.     }
  416.  
  417.     return false;
  418. }
Add Comment
Please, Sign In to add comment