diff --git a/Content/Legumix/Drops/BP_AmmoPack.uasset b/Content/Legumix/Drops/BP_AmmoPack.uasset new file mode 100644 index 0000000..47b93b0 --- /dev/null +++ b/Content/Legumix/Drops/BP_AmmoPack.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea97fb259ec4d45f0113cafcdbac6977f07ae0f0b44653a507bc5fabcfe0e580 +size 36895 diff --git a/Content/Legumix/Drops/BP_HealthPack.uasset b/Content/Legumix/Drops/BP_HealthPack.uasset new file mode 100644 index 0000000..7a17212 --- /dev/null +++ b/Content/Legumix/Drops/BP_HealthPack.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7fcc9655484fdc1ff6c4b04363ffce15be0efd046b1280fa25ea1681ea8f984 +size 37994 diff --git a/Content/Legumix/Drops/BP_ItemDrop.uasset b/Content/Legumix/Drops/BP_ItemDrop.uasset new file mode 100644 index 0000000..b3e5007 --- /dev/null +++ b/Content/Legumix/Drops/BP_ItemDrop.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:851274749e8bb9e7378a8ec14d2f68578b28aaa00718b2642496c3a657513eab +size 15573 diff --git a/Content/Legumix/Drops/C_AmmoPackDropRate.uasset b/Content/Legumix/Drops/C_AmmoPackDropRate.uasset new file mode 100644 index 0000000..591846b --- /dev/null +++ b/Content/Legumix/Drops/C_AmmoPackDropRate.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a31f19ca0afdf6dd5444538c95eb209d8b503feae769cf72f2b321baff0dd13 +size 5038 diff --git a/Content/Legumix/Spawner/DT_WavePreset.uasset b/Content/Legumix/Spawner/DT_WavePreset.uasset index 69cfca0..98efd95 100644 --- a/Content/Legumix/Spawner/DT_WavePreset.uasset +++ b/Content/Legumix/Spawner/DT_WavePreset.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4dc980d10370e54247d6d2b0bd1cd609110484abbbff020f22414b7261c5777 -size 2889 +oid sha256:0a8c14f41d1b2e5c1655d90dbbf4bf5ad091136fc028d831c2791b67dade66f5 +size 3973 diff --git a/Content/Legumix/Spawner/LVL_TestSpawn.umap b/Content/Legumix/Spawner/LVL_TestSpawn.umap index babf3e9..9b6ae55 100644 --- a/Content/Legumix/Spawner/LVL_TestSpawn.umap +++ b/Content/Legumix/Spawner/LVL_TestSpawn.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bcb5b01b681fff1a03e31833c07c4f3f7d7201fc37d0f0216cbc4714a96d1526 -size 81157 +oid sha256:36cb7d68cdfa4a650a8d7b5eda3ede2b57ebcd8d308d6b3e6a27ecd35fe5b7fc +size 81266 diff --git a/Source/LegumeMix/Private/Ammo/LMAmmoPack.cpp b/Source/LegumeMix/Private/Ammo/LMAmmoPack.cpp new file mode 100644 index 0000000..cfc4560 --- /dev/null +++ b/Source/LegumeMix/Private/Ammo/LMAmmoPack.cpp @@ -0,0 +1,10 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Ammo/LMAmmoPack.h" + + +ALMAmmoPack::ALMAmmoPack() +{ + PrimaryActorTick.bCanEverTick = false; +} diff --git a/Source/LegumeMix/Private/Ammo/LMItemDropComponent.cpp b/Source/LegumeMix/Private/Ammo/LMItemDropComponent.cpp new file mode 100644 index 0000000..8fcf066 --- /dev/null +++ b/Source/LegumeMix/Private/Ammo/LMItemDropComponent.cpp @@ -0,0 +1,61 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Ammo/LMItemDropComponent.h" + +#include "LMHealthPack.h" +#include "Ammo/LMAmmoPack.h" +#include "Kismet/GameplayStatics.h" +#include "Player/LMPlayer.h" +#include "Weapon/LMWeaponManager.h" +#include "Windows/WindowsApplication.h" + + +ULMItemDropComponent::ULMItemDropComponent() +{ + PrimaryComponentTick.bCanEverTick = false; +} + +void ULMItemDropComponent::TryDropItems() +{ + float Result = FMath::RandRange(0.f, 100.f); + + if (DropChanceHealthPack >= Result) + { + SpawnHealth(); + } + + if (ALMPlayer* Player = Cast(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0))) + { + Result = FMath::RandRange(0.f, 1.f); + const FLMAmmoData Ammo = Player->GetWeaponManager()->GetAmmoData(AmmoType); + const float Percentage = static_cast(Ammo.AmmoCount) / static_cast(Ammo.MaxAmmo); + const float DropChance = DropChanceAtRemainingAmmo->GetFloatValue(Percentage); + + FString Random = FString::Printf(TEXT("Drop Chance of %f for ammo (%i / %i) %f with random at %f"), DropChance, Ammo.AmmoCount, Ammo.MaxAmmo, Percentage, Result); + GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5.f, FColor::Green, Random); + if (DropChance >= Result) + { + SpawnAmmo(); + } + } +} + +void ULMItemDropComponent::SpawnAmmo() +{ + FActorSpawnParameters SpawnParams; + SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn; + + ALMAmmoPack* Pack = GetWorld()->SpawnActor(AmmoPack, GetOwner()->GetActorTransform(), SpawnParams); +} + +void ULMItemDropComponent::SpawnHealth() +{ + FActorSpawnParameters SpawnParams; + SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn; + + ALMHealthPack* Pack = GetWorld()->SpawnActor(HealthPack, GetOwner()->GetActorTransform(), SpawnParams); +} + + + diff --git a/Source/LegumeMix/Private/LMHealthPack.cpp b/Source/LegumeMix/Private/LMHealthPack.cpp new file mode 100644 index 0000000..51b9614 --- /dev/null +++ b/Source/LegumeMix/Private/LMHealthPack.cpp @@ -0,0 +1,11 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "LMHealthPack.h" + + +ALMHealthPack::ALMHealthPack() +{ + PrimaryActorTick.bCanEverTick = false; +} + diff --git a/Source/LegumeMix/Private/LMItemDrop.cpp b/Source/LegumeMix/Private/LMItemDrop.cpp new file mode 100644 index 0000000..de74b26 --- /dev/null +++ b/Source/LegumeMix/Private/LMItemDrop.cpp @@ -0,0 +1,25 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "LMItemDrop.h" + + +ALMItemDrop::ALMItemDrop() +{ + PrimaryActorTick.bCanEverTick = true; + StaticMeshComponent = CreateDefaultSubobject("MeshComponent"); + RootComponent = StaticMeshComponent; +} + +void ALMItemDrop::BeginPlay() +{ + Super::BeginPlay(); + GetWorldTimerManager().SetTimer(DespawnHandle, this, &ALMItemDrop::Despawn, TimeBeforeDespawn); +} + +void ALMItemDrop::Despawn() +{ + GetWorldTimerManager().ClearTimer(DespawnHandle); + Destroy(); +} + diff --git a/Source/LegumeMix/Private/LMSpawnPosition.cpp b/Source/LegumeMix/Private/LMSpawnPosition.cpp index 6aaa7ec..c8a727d 100644 --- a/Source/LegumeMix/Private/LMSpawnPosition.cpp +++ b/Source/LegumeMix/Private/LMSpawnPosition.cpp @@ -14,7 +14,7 @@ ALMSpawnPosition::ALMSpawnPosition() } -bool ALMSpawnPosition::CanSpawn() const +bool ALMSpawnPosition::CanSpawn() { return !IsPlayerVisible() && !IsOnCooldow; } @@ -59,7 +59,7 @@ bool ALMSpawnPosition::IsPlayerVisible() const if (bHit) { //UE_LOG(LogTemp, Warning, TEXT("LineTrace Hit: %s"), *HitResult.GetActor()->GetName()); - return HitResult.GetActor() == Player; // Retourne true uniquement si l'acteur touché est le joueur + return (HitResult.GetActor() == Player && !IsOnCooldow); // Retourne true uniquement si l'acteur touché est le joueur } //UE_LOG(LogTemp, Warning, TEXT("LineTrace: No Hit")); @@ -69,12 +69,14 @@ bool ALMSpawnPosition::IsPlayerVisible() const void ALMSpawnPosition::StarCooldown() { IsOnCooldow = true; + UE_LOG(LogTemp, Warning, TEXT("Spawner Cooldown")); GetWorld()->GetTimerManager().SetTimer(ProcessCooldown, this, &ALMSpawnPosition::EndCooldown, TimerCooldown, false); } void ALMSpawnPosition::EndCooldown() { IsOnCooldow = false; + UE_LOG(LogTemp, Warning, TEXT("Spawner End Cooldown")); } diff --git a/Source/LegumeMix/Private/LMWaveManager.cpp b/Source/LegumeMix/Private/LMWaveManager.cpp index 2e4427c..d19dc78 100644 --- a/Source/LegumeMix/Private/LMWaveManager.cpp +++ b/Source/LegumeMix/Private/LMWaveManager.cpp @@ -37,7 +37,7 @@ void ALMWaveManager::SpawnEnemy(ALMSpawnPosition* spawnPosition) if (!tempEnemy) { - UE_LOG(LogTemp, Error, TEXT("Failed to spawn enemy!")); + //UE_LOG(LogTemp, Error, TEXT("Failed to spawn enemy!")); return; } spawnPosition->StarCooldown(); @@ -50,7 +50,7 @@ void ALMWaveManager::SpawnEnemy(ALMSpawnPosition* spawnPosition) //bind la method ennemydead à la death de l'ennemis tempEnemy->OnEnemyDeath.AddDynamic(this, &ALMWaveManager::EnemyDead); - UE_LOG(LogTemp, Error, TEXT("Succes to spawn and bind on death method")); + //UE_LOG(LogTemp, Error, TEXT("Succes to spawn and bind on death method")); EnemySpawned++; EnemiesPerType[RandomIndex]--; @@ -65,15 +65,9 @@ void ALMWaveManager::EnemyDead(ALMEnemy* enemyToRemoveFromLife) bool ALMWaveManager::RemainsEnemyToSpawn() { - int TotalEnemies = 0; - - for (int EnemyCount : EnemiesPerType) - { - TotalEnemies += EnemyCount; - } - bool stillToSpawn = TotalEnemies !=0; - bool no = EnemyAliveList.Num() < MaxEnemyInstantiate; - return EnemyNumberInWave != EnemySpawned && no && stillToSpawn; + bool StillToSpawn = TotalOfEnemyToStillSpawn() !=0; + bool NoEnemyLeftToSpawn = EnemyAliveList.Num() < MaxEnemyInstantiate; + return EnemyNumberInWave != EnemySpawned && NoEnemyLeftToSpawn && StillToSpawn; } void ALMWaveManager::CheckForSpawnerOK() @@ -88,6 +82,17 @@ void ALMWaveManager::CheckForSpawnerOK() } } +int ALMWaveManager::TotalOfEnemyToStillSpawn() +{ + int TotalEnemies = 0; + + for (int EnemyCount : EnemiesPerType) + { + TotalEnemies += EnemyCount; + } + return TotalEnemies; +} + void ALMWaveManager::GetRandomDataWaveRow() { TArray RowNames = WaveDatePreset->GetRowNames(); @@ -97,17 +102,18 @@ void ALMWaveManager::GetRandomDataWaveRow() CurrentWaveName = WaveName.ToString(); FLMWaveStructure* InfoWaveRow = WaveDatePreset->FindRow(WaveName, ""); - - //InternalEnemyRatio = InfoWaveRow->WaveComposition; + EnemyNumberInWave = InfoWaveRow->EnemyCount; MaxEnemyInstantiate = InfoWaveRow->MaxEnemyCount; - + + AllEnemyType.Empty(); for (const FLMEnemyRatio& EnemyRatio : InfoWaveRow->WaveComposition) { // Ajoute chaque EnemyType à la liste AllEnemyType.Add(EnemyRatio.EnemyType); } + EnemiesPerType.Empty(); // Récupère les ratios (NbEnemy) et calcule leur somme int32 TotalRatio = 0; for (const FLMEnemyRatio& EnemyRatio : InfoWaveRow->WaveComposition) @@ -140,23 +146,29 @@ void ALMWaveManager::GetRandomDataWaveRow() void ALMWaveManager::Tick(float DeltaTime) { Super::Tick(DeltaTime); - if(RemainsEnemyToSpawn()) + if(!OnCooldown) { - CheckForSpawnerOK(); - if(SpawnPositionsOK.Num() > 0) + if(RemainsEnemyToSpawn()) { - //Choose spawnpoint to spawn - int32 RandomIndex = FMath::RandRange(0, SpawnPositionsOK.Num() - 1); - SpawnEnemy(SpawnPositionsOK[RandomIndex]); - EnemySpawned++; + CheckForSpawnerOK(); + if(SpawnPositionsOK.Num() > 0) + { + //Choose spawnpoint to spawn + int32 RandomIndex = FMath::RandRange(0, SpawnPositionsOK.Num() - 1); + SpawnEnemy(SpawnPositionsOK[RandomIndex]); + } + return; + } + if(TotalOfEnemyToStillSpawn() == 0 && EnemyAliveList.Num() == 0) + { + //lauch break time + // Lance un breaktime avant de relancer une wave + UE_LOG(LogTemp, Warning, TEXT("Start a new wave")); + OnCooldown = true; + GetWorld()->GetTimerManager().SetTimer(BreakTimer, this, &ALMWaveManager::StartWave, BreakTime, false); } } - else - { - //lauch break time - // Lance un timer de 3 secondes avant d'appeler StartWave() - GetWorld()->GetTimerManager().SetTimer(BreakTimer, this, &ALMWaveManager::StartWave, BreakTime, false); - } + } @@ -164,4 +176,5 @@ void ALMWaveManager::StartWave() { GetRandomDataWaveRow(); EnemySpawned = 0; + OnCooldown = false; } diff --git a/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp b/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp index f5e1a13..86cc68e 100644 --- a/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp +++ b/Source/LegumeMix/Private/Weapon/LMWeaponManager.cpp @@ -143,6 +143,11 @@ int ULMWeaponManager::GetAmmoCount(const EAmmoType AmmoType) return 0; } +FLMAmmoData& ULMWeaponManager::GetAmmoData(const EAmmoType AmmoType) +{ + return AmmoData[AmmoType]; +} + void ULMWeaponManager::Fire() { ALMWeaponBase* Weapon = GetCurrentWeapon(); diff --git a/Source/LegumeMix/Public/Ammo/LMAmmoPack.h b/Source/LegumeMix/Public/Ammo/LMAmmoPack.h new file mode 100644 index 0000000..71d1d65 --- /dev/null +++ b/Source/LegumeMix/Public/Ammo/LMAmmoPack.h @@ -0,0 +1,24 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "LMAmmoType.h" +#include "LMItemDrop.h" +#include "LMAmmoPack.generated.h" + +UCLASS() +class LEGUMEMIX_API ALMAmmoPack : public ALMItemDrop +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0)) + int AmmoCount = 6; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + EAmmoType AmmoType = EAmmoType::EAT_CornAmmo; + +public: + ALMAmmoPack(); +}; diff --git a/Source/LegumeMix/Public/Ammo/LMItemDropComponent.h b/Source/LegumeMix/Public/Ammo/LMItemDropComponent.h new file mode 100644 index 0000000..fbef531 --- /dev/null +++ b/Source/LegumeMix/Public/Ammo/LMItemDropComponent.h @@ -0,0 +1,42 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "LMAmmoType.h" +#include "Components/ActorComponent.h" +#include "LMItemDropComponent.generated.h" + +class ALMAmmoPack; +class ALMHealthPack; + +UCLASS(Blueprintable, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) +class LEGUMEMIX_API ULMItemDropComponent : public UActorComponent +{ + GENERATED_BODY() + +private: + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + TObjectPtr DropChanceAtRemainingAmmo; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0, ClampMax=100, UIMin=0, UIMax=100)) + float DropChanceHealthPack = 10.f; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + EAmmoType AmmoType = EAmmoType::EAT_CornAmmo; + + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + TSubclassOf AmmoPack; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true)) + TSubclassOf HealthPack; + +public: + ULMItemDropComponent(); + + UFUNCTION(BlueprintCallable) + void TryDropItems(); + UFUNCTION(BlueprintCallable) + void SpawnAmmo(); + UFUNCTION(BlueprintCallable) + void SpawnHealth(); +}; diff --git a/Source/LegumeMix/Public/LMHealthPack.h b/Source/LegumeMix/Public/LMHealthPack.h new file mode 100644 index 0000000..ef6f956 --- /dev/null +++ b/Source/LegumeMix/Public/LMHealthPack.h @@ -0,0 +1,20 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "LMItemDrop.h" +#include "LMHealthPack.generated.h" + +UCLASS() +class LEGUMEMIX_API ALMHealthPack : public ALMItemDrop +{ + GENERATED_BODY() + +public: + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0)) + float HealthGain = 10.f; + +public: + ALMHealthPack(); +}; diff --git a/Source/LegumeMix/Public/LMItemDrop.h b/Source/LegumeMix/Public/LMItemDrop.h new file mode 100644 index 0000000..423c7dd --- /dev/null +++ b/Source/LegumeMix/Public/LMItemDrop.h @@ -0,0 +1,33 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "LMItemDrop.generated.h" + +class ULMDropData; + +UCLASS() +class LEGUMEMIX_API ALMItemDrop : public AActor +{ + GENERATED_BODY() + +protected: + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix) + float TimeBeforeDespawn = 30.f; + +private: + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true)) + TObjectPtr StaticMeshComponent; + + FTimerHandle DespawnHandle; + +public: + ALMItemDrop(); + virtual void BeginPlay() override; + +protected: + UFUNCTION(BlueprintCallable) + void Despawn(); +}; diff --git a/Source/LegumeMix/Public/LMSpawnPosition.h b/Source/LegumeMix/Public/LMSpawnPosition.h index 3a118c3..8542849 100644 --- a/Source/LegumeMix/Public/LMSpawnPosition.h +++ b/Source/LegumeMix/Public/LMSpawnPosition.h @@ -16,7 +16,7 @@ public: ALMSpawnPosition(); // Méthode pour vérifier si le spawn est possible - bool CanSpawn() const; + virtual bool CanSpawn(); UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"), Category = "Legumix") float TimerCooldown = 1.5; void StarCooldown(); diff --git a/Source/LegumeMix/Public/LMWaveManager.h b/Source/LegumeMix/Public/LMWaveManager.h index 83ec789..bea087d 100644 --- a/Source/LegumeMix/Public/LMWaveManager.h +++ b/Source/LegumeMix/Public/LMWaveManager.h @@ -43,6 +43,9 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix") TArray> AllEnemyType; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix") + int EnemySpawned = 0; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix") TArray EnemiesPerType; @@ -55,6 +58,7 @@ protected: virtual void EnemyDead(ALMEnemy* enemyToRemoveFromLife); virtual bool RemainsEnemyToSpawn(); virtual void CheckForSpawnerOK(); + virtual int TotalOfEnemyToStillSpawn(); virtual void GetRandomDataWaveRow(); @@ -64,7 +68,7 @@ public: private: TArray SpawnPositionsOK; - int EnemySpawned = 0; FTimerHandle BreakTimer; + bool OnCooldown; }; diff --git a/Source/LegumeMix/Public/Weapon/LMWeaponManager.h b/Source/LegumeMix/Public/Weapon/LMWeaponManager.h index 5577da2..31e4b36 100644 --- a/Source/LegumeMix/Public/Weapon/LMWeaponManager.h +++ b/Source/LegumeMix/Public/Weapon/LMWeaponManager.h @@ -38,6 +38,8 @@ public: bool AddAmmoType(EAmmoType AmmoType, int AmmoCount); UFUNCTION(BlueprintCallable, Category=Legumix) int GetAmmoCount(EAmmoType AmmoType); + UFUNCTION(BlueprintCallable, Category=Legumix) + FLMAmmoData& GetAmmoData(EAmmoType AmmoType); UFUNCTION(BlueprintCallable, Category=Legumix) void Fire();