// Fill out your copyright notice in the Description page of Project Settings. #include "PartySubsystem.h" #include "Unit.h" #include "UpgradeSubsystem.h" #include "Kismet/GameplayStatics.h" int32 UPartySubsystem::SpawnParty(const float InVerticalSpacing, const float InHorizontalOffset, const float InHorizontalSpacing, const int InNumRows) { this->VerticalSpacing = InVerticalSpacing; this->HorizontalOffset = InHorizontalOffset; this->NumRows = InNumRows; this->HorizontalSpacing = InHorizontalSpacing; CurrentColumn = 0; LastSpawnIndex = 0; SpawnQueue.Empty(); TArray SpawnPoints; UGameplayStatics::GetAllActorsWithTag(GetWorld(), "PlayerSpawn", SpawnPoints); SpawnPoint = SpawnPoints[0]; for (UPartyMember* Unit : PartyMembers) { for(auto i = 0; i < Unit->GetAllocated(); i++) { SpawnQueue.Add(Unit->UnitInfo->GetCharacterClass()); } } const int32 NumUnits = SpawnQueue.Num(); SpawnUnits(); GetWorld()->GetTimerManager().SetTimer( SpawnTimerHandle, this, &UPartySubsystem::SpawnUnits, 0.5f, true); return NumUnits; } void UPartySubsystem::SpawnUnits() { for(auto i = 0; i < NumRows; i++) { if(i + LastSpawnIndex >= SpawnQueue.Num()) { GetWorld()->GetTimerManager().ClearTimer(SpawnTimerHandle); LastSpawnIndex += i; return; } FActorSpawnParameters SpawnActorParameters = {}; SpawnActorParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn; FVector Location = SpawnPoint->GetActorLocation() + FVector(i * -VerticalSpacing + FMath::RandRange(-500.0f, 500.0f), -HorizontalOffset * CurrentColumn + FMath::RandRange(-500.0f, 500.0f), 300); FRotator Rotation = FRotator(0, 90.0f, 0); AActor* NewActor = GetWorld()->SpawnActor(SpawnQueue[i + LastSpawnIndex], &Location, &Rotation, SpawnActorParameters); if(NewActor != nullptr) { NewActor->Tags.Add(TEXT("player")); TObjectPtr NewUnit = Cast(NewActor); if(NewUnit != nullptr) { GetWorld()->GetFirstLocalPlayerFromController()->GetSubsystem()->ApplyUnitUpgrades(NewUnit); } } FHitResult Hit; FVector TraceStart = NewActor->GetActorLocation(); FVector TraceEnd = -NewActor->GetActorUpVector() * 10000.0f; FCollisionQueryParams QueryParams; QueryParams.AddIgnoredActor(NewActor); NewActor->GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_WorldStatic, QueryParams); if(Hit.bBlockingHit) { NewActor->SetActorLocation(Hit.Location, true, nullptr, ETeleportType::ResetPhysics); } } LastSpawnIndex += NumRows; CurrentColumn++; } void UPartySubsystem::SetCredits(const int32 Amount) { Credits = Amount; } int32 UPartySubsystem::GetTotalAvailablePartyMembers() { int32 Total = 0; for(auto const Member : PartyMembers) { Total += Member->GetAvailable(); } return Total; } int32 UPartySubsystem::GetTotalAllocatedPartyMembers() { int32 Total = 0; for(auto const Member : PartyMembers) { Total += Member->GetAllocated(); } return Total; } TArray UPartySubsystem::GetMembersInTier(const int32 Tier) { TArray TierMembers; for(auto Member : PartyMembers) { if (Member->UnitInfo->GetTier() == Tier) { TierMembers.Add(Member); } } return TierMembers; }