300 lines
7.1 KiB
C++
300 lines
7.1 KiB
C++
#include "UnrealProject.h"
|
|
#include "SpawnerBase.h"
|
|
#include "CharacterBase.h"
|
|
#include "ItemBase.h"
|
|
#include "BaseSkillObject.h"
|
|
#include "WiebertAnimation.h"
|
|
#include "DefaultGameState.h"
|
|
#include "MainCharacterAnimation.h"
|
|
#include "SkillTreeState.h"
|
|
|
|
|
|
ACharacterBase::ACharacterBase()
|
|
{
|
|
m_team = 0;
|
|
bReplicates = true;
|
|
|
|
visionRadius = 1000;
|
|
}
|
|
|
|
void ACharacterBase::BeginPlay()
|
|
{
|
|
Super::BeginPlay();
|
|
|
|
// If this actor is attached to a spawner base, it must be ignored
|
|
AActor* const parent = GetAttachParentActor();
|
|
if (parent != nullptr && parent->IsA<ASpawnerBase>())
|
|
return;
|
|
|
|
// Register to the minimap
|
|
UWorld* const world = GetWorld();
|
|
if (IsValid(world))
|
|
{
|
|
ADefaultGameState* const gameState = Cast<ADefaultGameState>(world->GetGameState());
|
|
if (IsValid(gameState))
|
|
{
|
|
const FVector location = GetActorLocation();
|
|
minimapHandle.position = FVector2D(location.X, location.Y);
|
|
minimapHandle.character = this;
|
|
gameState->minimapQuadtree.AddObject(minimapHandle);
|
|
}
|
|
}
|
|
}
|
|
void ACharacterBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|
{
|
|
Super::EndPlay(EndPlayReason);
|
|
|
|
// Unregister to the minimap
|
|
ADefaultGameState* const gameState = Cast<ADefaultGameState>(GetWorld()->GetGameState());
|
|
if (IsValid(gameState) && minimapHandle.root)
|
|
gameState->minimapQuadtree.RemoveObject(minimapHandle);
|
|
|
|
minimapHandle.root = nullptr;
|
|
minimapHandle.node = nullptr;
|
|
minimapHandle.character = nullptr;
|
|
}
|
|
void ACharacterBase::Tick(float deltaTime)
|
|
{
|
|
Super::Tick(deltaTime);
|
|
|
|
const FVector location = GetActorLocation();
|
|
minimapHandle.position = FVector2D(location.X, location.Y);
|
|
}
|
|
|
|
void ACharacterBase::m_EquipSkills_Implementation(const TArray<UBaseSkillObject*>& skills)
|
|
{
|
|
for(UBaseSkillObject* skill : skills)
|
|
{
|
|
// Check if not yet equiped
|
|
if(!m_equipedSkills.Contains(skill))
|
|
{
|
|
AItemBase::CreateItemsFromSkill(GetWorld(), skill, this);
|
|
m_equipedSkills.Add(skill);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::EquipSkills(const TArray<UBaseSkillObject*>& skills)
|
|
{
|
|
m_EquipSkills(skills);
|
|
}
|
|
void ACharacterBase::EquipSkillsFromSkillTreeState(const struct FSkillTreeState& skState)
|
|
{
|
|
TArray<UBaseSkillObject*> skillObjects;
|
|
for(const FSkillTreeStateObject& obj : skState.objects)
|
|
{
|
|
UBaseSkillObject* skillObj = obj.skillObject->GetDefaultObject<UBaseSkillObject>();
|
|
if(!skillObj)
|
|
continue;
|
|
skillObjects.Add(skillObj);
|
|
}
|
|
m_EquipSkills(skillObjects);
|
|
}
|
|
void ACharacterBase::EquipItems_Implementation(const TArray<TSubclassOf<AItemBase>>& itemClasses)
|
|
{
|
|
for(auto& itemClass : itemClasses)
|
|
{
|
|
EquipItem_Implementation(itemClass);
|
|
}
|
|
}
|
|
void ACharacterBase::EquipItem_Implementation(TSubclassOf<class AItemBase> itemClass)
|
|
{
|
|
if(itemClass == nullptr)
|
|
return;
|
|
|
|
AItemBase* item = GetWorld()->SpawnActor<AItemBase>(itemClass);
|
|
AItemBase* existing = AItemBase::CheckSlotOccupied(item->type, this);
|
|
if(existing)
|
|
existing->Destroy();
|
|
if(item)
|
|
{
|
|
if(!item->AttachItemToCharacter(this))
|
|
{
|
|
item->Destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::SendInitialAppearance(APlayerController* pc)
|
|
{
|
|
if(Role == ROLE_Authority)
|
|
{
|
|
m_ReceiveInitialAppearance(pc, GetEquipedSkills(), GetCharacterCustomization());
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::m_ReceiveInitialAppearance_Implementation(APlayerController* pc, const TArray<class UBaseSkillObject*>& itemClasses, const FCharacterCustomization& cc)
|
|
{
|
|
APlayerController* localPC = GetGameInstance()->GetFirstLocalPlayerController();
|
|
if(pc == localPC)
|
|
{
|
|
EquipSkills(itemClasses);
|
|
SetCustomizations_Implementation(cc);
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::Destroyed()
|
|
{
|
|
auto destroyItems = m_items;
|
|
for(auto item : destroyItems)
|
|
{
|
|
if(IsValid(item))
|
|
{
|
|
item->Destroy();
|
|
}
|
|
}
|
|
Super::Destroyed();
|
|
}
|
|
|
|
TArray<TSubclassOf<AItemBase>> ACharacterBase::GetEquipedItemClasses() const
|
|
{
|
|
TArray<TSubclassOf<AItemBase>> ret;
|
|
for(auto item : m_items)
|
|
{
|
|
ret.Add(item->GetClass());
|
|
}
|
|
return ret;
|
|
}
|
|
const TArray<class AItemBase*>& ACharacterBase::GetEquipedItems() const
|
|
{
|
|
return m_items;
|
|
}
|
|
|
|
const FCharacterCustomization& ACharacterBase::GetCharacterCustomization() const
|
|
{
|
|
static FCharacterCustomization dummy;
|
|
USkeletalMeshComponent* skMesh = GetMesh();
|
|
if(skMesh)
|
|
{
|
|
UWiebertAnimation* animBP = Cast<UWiebertAnimation>(skMesh->GetAnimInstance());
|
|
if(animBP)
|
|
{
|
|
return animBP->charCustomization;
|
|
}
|
|
else
|
|
{
|
|
UMainCharacterAnimation* charBP = Cast<UMainCharacterAnimation>(skMesh->GetAnimInstance());
|
|
if (charBP)
|
|
{
|
|
return charBP->charCustomization;
|
|
}
|
|
}
|
|
}
|
|
return dummy;
|
|
}
|
|
|
|
const TArray<class UBaseSkillObject*>& ACharacterBase::GetEquipedSkills() const
|
|
{
|
|
return m_equipedSkills;
|
|
}
|
|
|
|
void ACharacterBase::UnequipSkills_Implementation(const TArray<UBaseSkillObject*>& skills)
|
|
{
|
|
for(auto skill : skills)
|
|
{
|
|
if(m_equipedSkills.Contains(skill))
|
|
{
|
|
TArray<AItemBase*> items;
|
|
m_mappedItems.MultiFind(skill, items);
|
|
for(auto item : items)
|
|
item->Destroy();
|
|
m_equipedSkills.Remove(skill);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::ClearEquipment_Implementation()
|
|
{
|
|
auto clearItems = m_items;
|
|
for(auto item : clearItems)
|
|
{
|
|
if(IsValid(item))
|
|
{
|
|
item->Destroy();
|
|
}
|
|
}
|
|
m_mappedItems.Reset();
|
|
m_equipedSkills.SetNum(0);
|
|
m_items.SetNum(0);
|
|
}
|
|
void ACharacterBase::SetCustomizations_Implementation(const FCharacterCustomization& cc)
|
|
{
|
|
USkeletalMeshComponent* skMesh = GetMesh();
|
|
if(skMesh)
|
|
{
|
|
UWiebertAnimation* animBP = Cast<UWiebertAnimation>(skMesh->GetAnimInstance());
|
|
if(animBP)
|
|
{
|
|
animBP->SetCharacterCustomization(cc);
|
|
}
|
|
else
|
|
{
|
|
UMainCharacterAnimation* charBP = Cast<UMainCharacterAnimation>(skMesh->GetAnimInstance());
|
|
if (charBP)
|
|
{
|
|
charBP->SetCharacterCustomization(cc);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GERROR("Can't set customization, no skeletal mesh on character");
|
|
}
|
|
}
|
|
|
|
void ACharacterBase::m_OnItemAdded(AItemBase* item)
|
|
{
|
|
// Add item to list of items assigned to given skill object
|
|
if(item->skillObject)
|
|
m_mappedItems.Add(item->skillObject, item);
|
|
m_items.Add(item);
|
|
}
|
|
void ACharacterBase::m_OnItemRemoved(AItemBase* item)
|
|
{
|
|
// Remove mapped item
|
|
m_mappedItems.RemoveSingle(item->skillObject, item);
|
|
m_items.Remove(item);
|
|
}
|
|
|
|
void ACharacterBase::m_OnRep_Team()
|
|
{
|
|
|
|
}
|
|
|
|
int32 ACharacterBase::GetTeam() const
|
|
{
|
|
return m_team;
|
|
}
|
|
void ACharacterBase::SetTeam(int32 team)
|
|
{
|
|
check(Role == ROLE_Authority); // Server only call
|
|
m_team = team;
|
|
m_OnRep_Team();
|
|
}
|
|
|
|
void ACharacterBase::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
{
|
|
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
|
|
DOREPLIFETIME(ACharacterBase, m_team);
|
|
DOREPLIFETIME(ACharacterBase, playerName);
|
|
}
|
|
|
|
void ACharacterBase::RegisterEffect(class AEffect* effect)
|
|
{
|
|
if(effect != nullptr)
|
|
m_effects.Add(effect);
|
|
}
|
|
void ACharacterBase::UnRegisterEffect(class AEffect* effect)
|
|
{
|
|
if(effect == nullptr)
|
|
{
|
|
FWARNING("invalid effect is unregistering");
|
|
return;
|
|
}
|
|
m_effects.Remove(effect);
|
|
}
|
|
TArray<class AEffect*> ACharacterBase::GetEffects()
|
|
{
|
|
return m_effects;
|
|
} |