<commit_before>// Â© 2014 - 2017 Soverance Studios
// http://www.soverance.com

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Ethereal.h"
#include "Characters/Enemy/Boss/Zhan.h"
#include "AI/EnemyAI.h"
#include "EtherealEnemyMaster.h"

// Sets default values
AEtherealEnemyMaster::AEtherealEnemyMaster(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	// Get Assets, References Obtained Via Right Click in Editor
	static ConstructorHelpers::FObjectFinder<UBehaviorTree> BehaviorTreeObject(TEXT("BehaviorTree'/Game/Blueprints/Characters/Enemy/EnemyBT.EnemyBT'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> HitParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/P_blood_splash.P_blood_splash'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> DeathParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/EnemyDeath.EnemyDeath'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> DisappearParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/EnemyDisappear.EnemyDisappear'"));
	static ConstructorHelpers::FObjectFinder<USoundCue> DisappearAudioObject(TEXT("SoundCue'/Game/Audio/Party/EnemyDisappear_Cue.EnemyDisappear_Cue'"));

	EnemyBehavior = BehaviorTreeObject.Object; // Set Behavior Tree
	AIControllerClass = AEnemyAI::StaticClass();  // Set AI Class	
	
	// Set Default Objects
	P_HitFX = HitParticleObject.Object;
	P_DeathFX = DeathParticleObject.Object;
	P_DisappearFX = DisappearParticleObject.Object;
	S_DisappearAudio = DisappearAudioObject.Object;

	// Create stuff
	HitFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("HitFX"));
	HitFX->SetupAttachment(RootComponent);
	DeathFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("DeathFX"));
	DeathFX->SetupAttachment(RootComponent);
	DisappearFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("DisappearFX"));
	DisappearFX->SetupAttachment(RootComponent);
	DisappearAudio = ObjectInitializer.CreateDefaultSubobject<UAudioComponent>(this, TEXT("DisappearAudio"));
	DisappearAudio->SetupAttachment(RootComponent);
	
	// Assignment
	HitFX->Template = P_HitFX;
	DeathFX->Template = P_DeathFX;
	DisappearFX->Template = P_DisappearFX;
	DisappearAudio->Sound = S_DisappearAudio;
	

	HitFX->bAutoActivate = false;
	DeathFX->bAutoActivate = false;
	DisappearFX->bAutoActivate = false;
	DisappearAudio->bAutoActivate = false;
	
	MapMarkerFX->SetColorParameter(FName(TEXT("BeamColor")), FColor::Red);
}

// Called when the game starts or when spawned
void AEtherealEnemyMaster::BeginPlay()
{
	Super::BeginPlay();

	ToggleReticle(false);  // toggles the reticle off at start
	StopHit();  // begin calling StopHit()

	// iterate through the world for all Ethereal Player Masters. Since this is a single player game, we know the enemy's target will always be this one actor.
	for (TActorIterator<AEtherealPlayerMaster> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		Target = *ActorItr; // get the instance of the Player Master

		if (Target)
		{
			EtherealGameInstance = Target->EtherealGameInstance;  // sets the reference to the EtherealGameInstance, using the player's previously stored reference.

			if (EtherealGameInstance)
			{
				// Set all Volume Controls
				EtherealGameInstance->SetAudioVolume(DisappearAudio, EAudioTypes::AT_SoundEffect); 
			}

			// Bind the Map Marker functions
			Target->MapOpened.AddDynamic(this, &AEtherealCharacterMaster::ShowMapMarker);
			Target->MapClosed.AddDynamic(this, &AEtherealCharacterMaster::HideMapMarker);
		}		
	}
}

// Called every frame
void AEtherealEnemyMaster::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (!IsDead) // if enemy is not dead
	{
		if (InRange)  // if is in range of player
		{
			if (IsAggroed)  // if is aggroed to the player
			{
				if (GetDistanceTo(Target) > PawnSensing->SightRadius)  // if the player gets out of the enemy's sight radius
				{
					// Lost sight of player, disable aggro
					InRange = false;
					Deaggro();
				}
			}
		}
	}
}



// Sets the Enemy's default stats
void AEtherealEnemyMaster::SetBaseStats()
{
	float HPMod = 0;
	float StatMod = 0.0f;

	if (BattleType == EBattleTypes::BT_Signet) // High stats for SNMs
	{
		HPMod = 3500;
		StatMod = 10.0f;
	}
	if (BattleType == EBattleTypes::BT_Boss) // High stats for bosses
	{
		HPMod = 2000;
		StatMod = 7.5f;
	}
	if (BattleType == EBattleTypes::BT_Standard) // lower stats for regular enemies
	{
		HPMod = 200;
		StatMod = 5.1f;	
	}

	HP_Current = Level * HPMod;
	HP_Max = Level * HPMod;
	ATK = Level * StatMod;
	DEF = Level * StatMod;
	SPD = Level * StatMod;
}

// Force HP Caps keeps the enemy's HP between 0 and Max
bool AEtherealEnemyMaster::ForceHPCaps()<commit_msg>Enemy Base Stat Variations<commit_after>// Â© 2014 - 2017 Soverance Studios
// http://www.soverance.com

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Ethereal.h"
#include "Characters/Enemy/Boss/Zhan.h"
#include "AI/EnemyAI.h"
#include "EtherealEnemyMaster.h"

// Sets default values
AEtherealEnemyMaster::AEtherealEnemyMaster(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	// Get Assets, References Obtained Via Right Click in Editor
	static ConstructorHelpers::FObjectFinder<UBehaviorTree> BehaviorTreeObject(TEXT("BehaviorTree'/Game/Blueprints/Characters/Enemy/EnemyBT.EnemyBT'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> HitParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/P_blood_splash.P_blood_splash'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> DeathParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/EnemyDeath.EnemyDeath'"));
	static ConstructorHelpers::FObjectFinder<UParticleSystem> DisappearParticleObject(TEXT("ParticleSystem'/Game/Particles/Emitter/EnemyDisappear.EnemyDisappear'"));
	static ConstructorHelpers::FObjectFinder<USoundCue> DisappearAudioObject(TEXT("SoundCue'/Game/Audio/Party/EnemyDisappear_Cue.EnemyDisappear_Cue'"));

	EnemyBehavior = BehaviorTreeObject.Object; // Set Behavior Tree
	AIControllerClass = AEnemyAI::StaticClass();  // Set AI Class	
	
	// Set Default Objects
	P_HitFX = HitParticleObject.Object;
	P_DeathFX = DeathParticleObject.Object;
	P_DisappearFX = DisappearParticleObject.Object;
	S_DisappearAudio = DisappearAudioObject.Object;

	// Create stuff
	HitFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("HitFX"));
	HitFX->SetupAttachment(RootComponent);
	DeathFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("DeathFX"));
	DeathFX->SetupAttachment(RootComponent);
	DisappearFX = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("DisappearFX"));
	DisappearFX->SetupAttachment(RootComponent);
	DisappearAudio = ObjectInitializer.CreateDefaultSubobject<UAudioComponent>(this, TEXT("DisappearAudio"));
	DisappearAudio->SetupAttachment(RootComponent);
	
	// Assignment
	HitFX->Template = P_HitFX;
	DeathFX->Template = P_DeathFX;
	DisappearFX->Template = P_DisappearFX;
	DisappearAudio->Sound = S_DisappearAudio;
	

	HitFX->bAutoActivate = false;
	DeathFX->bAutoActivate = false;
	DisappearFX->bAutoActivate = false;
	DisappearAudio->bAutoActivate = false;
	
	MapMarkerFX->SetColorParameter(FName(TEXT("BeamColor")), FColor::Red);
}

// Called when the game starts or when spawned
void AEtherealEnemyMaster::BeginPlay()
{
	Super::BeginPlay();

	ToggleReticle(false);  // toggles the reticle off at start
	StopHit();  // begin calling StopHit()

	// iterate through the world for all Ethereal Player Masters. Since this is a single player game, we know the enemy's target will always be this one actor.
	for (TActorIterator<AEtherealPlayerMaster> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		Target = *ActorItr; // get the instance of the Player Master

		if (Target)
		{
			EtherealGameInstance = Target->EtherealGameInstance;  // sets the reference to the EtherealGameInstance, using the player's previously stored reference.

			if (EtherealGameInstance)
			{
				// Set all Volume Controls
				EtherealGameInstance->SetAudioVolume(DisappearAudio, EAudioTypes::AT_SoundEffect); 
			}

			// Bind the Map Marker functions
			Target->MapOpened.AddDynamic(this, &AEtherealCharacterMaster::ShowMapMarker);
			Target->MapClosed.AddDynamic(this, &AEtherealCharacterMaster::HideMapMarker);
		}		
	}
}

// Called every frame
void AEtherealEnemyMaster::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (!IsDead) // if enemy is not dead
	{
		if (InRange)  // if is in range of player
		{
			if (IsAggroed)  // if is aggroed to the player
			{
				if (GetDistanceTo(Target) > PawnSensing->SightRadius)  // if the player gets out of the enemy's sight radius
				{
					// Lost sight of player, disable aggro
					InRange = false;
					Deaggro();
				}
			}
		}
	}
}



// Sets the Enemy's default stats
void AEtherealEnemyMaster::SetBaseStats()
{
	float HPMod = 0;  
	float StatMod = 0.0f; 

	if (BattleType == EBattleTypes::BT_Signet) // High stats for SNMs
	{
		HPMod = 3500;
		StatMod = 10.0f;
	}
	if (BattleType == EBattleTypes::BT_Boss) // High stats for bosses
	{
		HPMod = 2000;
		StatMod = 7.5f;
	}
	if (BattleType == EBattleTypes::BT_Standard) // lower stats for regular enemies
	{
		HPMod = 200;
		StatMod = 5.1f;	
	}

	// SET ALL STATS BASED ON CURRENT LEVEL + MODIFIERS
	HP_Current = Level * HPMod;
	HP_Max = Level * HPMod;
	// the randoms are just to add slight variations to the enemy's stats.
	ATK = (Level * StatMod) + FMath::RandRange(-3.0f, 3.0f);
	DEF = (Level * StatMod) + FMath::RandRange(-3.0f, 3.0f);
	SPD = (Level * StatMod) + FMath::RandRange(-3.0f, 3.0f);
}

// Force HP Caps keeps the enemy's HP between 0 and Max
bool AEtherealEnemyMaster::ForceHPCaps()
{'fraction_non_alphanumeric': 0.1060210602106021, 'fraction_numerical': 0.0072000720007200075, 'mean_word_length': 4.983844911147012, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5560292', 'n_tokens_mistral': 3794, 'n_tokens_neox': 3538, 'n_words': 884}