haxis/Source/UnrealProject/Creatures/CharacterBase.cpp

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;
}