2025-10-15 18:25:31 +08:00

343 lines
8.2 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "SkillManager.h"
#include "Skill.h"
#include "Kismet/GameplayStatics.h"
#include "ProjectFish/ProjectFishGameMode.h"
#include "ProjectFish/DataAsset/BagConfigAsset.h"
#include "ProjectFish/DataAsset/ShapeAsset.h"
USkillManager::USkillManager()
{
}
void USkillManager::Tick(float DeltaTime)
{
for (auto Skill : Skills)
{
Skill->TickSkill(DeltaTime);
}
}
bool USkillManager::IsTickable() const
{
return !bGameEnd && IsValid(GameMode) && GameMode->GetBattleIsBegin();
}
TStatId USkillManager::GetStatId() const
{
return Super::GetStatID();
}
void USkillManager::AddPawn(class APawnWithSkill* Pawn, FIntPoint BagSize)
{
if (!IsValid(GameMode))
{
GameMode = Cast<AProjectFishGameMode>(UGameplayStatics::GetGameMode(this));
}
PawnInfo.Add(Pawn, BagSize);
TMap<FIntPoint, int32> states;
for (int y = 0; y < BagSize.Y; y++)
{
for (int x = 0; x < BagSize.X; x++)
{
states.Add(FIntPoint(x, y), -1);
}
}
PawnBagState.Add(Pawn, states);
}
void USkillManager::AddBagWithSkills(UBagConfigAsset* Bag, APawnWithSkill* Pawn, TArray<USkill*>& SkillObjects,
TArray<FIntPoint>& BagPositions)
{
if (IsValid(Bag))
{
FIntPoint BagSize = *PawnInfo.Find(Pawn);
TMap<FIntPoint, int32>* states = PawnBagState.Find(Pawn);
for (auto PlacedSkill: Bag->PlacedSkills)
{
USkill* skill = NewObject<USkill>(this);
skill->InitSkill(Pawn, this, PlacedSkill);
SkillObjects.Add(skill);
BagPositions.Add(FIntPoint(PlacedSkill.PositionX, PlacedSkill.PositionY));
Skills.Add(skill);
//设置占用状态
for (int x = PlacedSkill.PositionX; x < PlacedSkill.PositionX + PlacedSkill.GetSkillSize().X; x++)
{
for (int y = PlacedSkill.PositionY; y < PlacedSkill.PositionY + PlacedSkill.GetSkillSize().Y; y++)
{
states->Add(FIntPoint(x, y) , GetSkillIndex(skill));
}
}
}
}
}
void USkillManager::OnAllSkillAdded()
{
//所有技能初始化后,初始化技能的触发器
for (auto Skill : Skills)
{
Skill->InitSkillTrigger();
}
}
int32 USkillManager::GetSkillIndex(USkill* Skill)
{
return Skills.Find(Skill);
}
TArray<USkill*> USkillManager::GetSkillsAround(USkill* TargetSkill)
{
TArray<USkill*> aroundSkills;
TMap<FIntPoint, int32> *BagStates = PawnBagState.Find(TargetSkill->GetOwner());
FIntPoint BagPos = TargetSkill->GetBagPos();
FIntPoint SkillSize = TargetSkill->GetSkillSize();
FIntPoint BagSize = *PawnInfo.Find(TargetSkill->GetOwner());
TObjectPtr<USkillAsset> data = TargetSkill->GetSkillData();
int beginX = FMath::Max(0, BagPos.X- 1);
int endX = FMath::Min(BagSize.X - 1, BagPos.X + SkillSize.X );
int beginY = FMath::Max(0, BagPos.Y - 1);
int endY = FMath::Min(BagSize.Y - 1, BagPos.Y + SkillSize.Y );
for (int x = beginX; x <= endX; x++)
{
for (int y = beginY; y <= endY; y++)
{
int32 skillIndex = *BagStates->Find(FIntPoint(x, y));
if (skillIndex != -1 && skillIndex != GetSkillIndex(TargetSkill) && !aroundSkills.Contains(Skills[skillIndex]))
{
aroundSkills.Add(Skills[skillIndex]);
}
}
}
return aroundSkills;
}
void USkillManager::RemoveSkill(USkill* Skill)
{
Skills.Remove(Skill);
}
TArray<APawnWithSkill*> USkillManager::GetAllPawns()
{
TArray<APawnWithSkill*> Pawns;
for (auto info: PawnInfo)
{
Pawns.Add(info.Key);
}
return Pawns;
}
APawnWithSkill* USkillManager::GetEnemyPawn(const APawnWithSkill* SelfPawn)
{
for (auto info: PawnInfo)
{
if (SelfPawn != info.Key)
return info.Key;
}
return nullptr;
}
TArray<class USkill*> USkillManager::GetSkillsByOwner(APawnWithSkill* Pawn)
{
TArray<class USkill*> skills;
for (auto Skill : Skills)
{
if (Skill->GetOwner() == Pawn)
skills.Add(Skill);
}
return skills;
}
TArray<class USkill*> USkillManager::GetSkillsByOwnerAndID(APawnWithSkill* Pawn, FGuid SkillID)
{
TArray<class USkill*> skills;
for (auto Skill : Skills)
{
if (Skill->GetOwner() == Pawn && Skill->GetSkillData()->SkillID == SkillID)
skills.Add(Skill);
}
return skills;
}
TArray< USkill*> USkillManager::GetAllSkills()
{
return Skills;
}
TArray<USkill*> USkillManager::GetSkillsByType(ESkillType SkillType) const
{
TArray<USkill*> Result;
for (USkill* Skill : Skills)
{
if (Skill && Skill->GetSkillData())
{
for (const ESkillType& Type : Skill->GetSkillData()->SkillTypes)
{
if (Type == SkillType)
{
Result.Add(Skill);
break;
}
}
}
}
return Result;
}
TArray<UObject*> USkillManager::GetTargetsBySelector( USkill* OwnerSkill, FTargetSelector TargetSelector)
{
TArray<UObject*> result;
switch (TargetSelector.SelecterType)
{
case EEffectTargetType::Target:
{
//目标是敌人
result.Add(GetEnemyPawn(OwnerSkill->GetOwner()));
break;;
}
case EEffectTargetType::Self:
{
//目标是敌人
result.Add(OwnerSkill->GetOwner());
break;;
}
case EEffectTargetType::TargetSkill:
{
TArray<USkill*> SpecifySkills = GetSkillsByOwner(GetEnemyPawn(OwnerSkill->GetOwner()));
//是否排除自身
if (!TargetSelector.bIncludeSelf)
{
SpecifySkills.Remove(OwnerSkill);
}
//全部还是指定数量随机
if (TargetSelector.bAll)
{
result.Append(SpecifySkills);
}
else
{
int TargetNum = FMath::Min(TargetSelector.MaxEffectTargetNum, SpecifySkills.Num());
for (int i = 0; i < TargetNum; i++)
{
int randomIndex = FMath::RandRange(0, SpecifySkills.Num() - 1);
result.Add(SpecifySkills[randomIndex]);
SpecifySkills.RemoveAt(randomIndex);
}
}
break;;
}
case EEffectTargetType::SelfSkill:
{
TArray<USkill*> SpecifySkills = GetSkillsByOwner(OwnerSkill->GetOwner());
//是否排除自身
if (!TargetSelector.bIncludeSelf)
{
SpecifySkills.Remove(OwnerSkill);
}
//全部还是指定数量随机
if (TargetSelector.bAll)
{
result.Append(SpecifySkills);
}
else
{
int TargetNum = FMath::Min(TargetSelector.MaxEffectTargetNum, SpecifySkills.Num());
for (int i = 0; i < TargetNum; i++)
{
int randomIndex = FMath::RandRange(0, SpecifySkills.Num() - 1);
result.Add(SpecifySkills[randomIndex]);
SpecifySkills.RemoveAt(randomIndex);
}
}
break;;
}
case EEffectTargetType::AroundSkill:
{
TArray<USkill*> aroundSpecifySkills = GetSkillsAround(OwnerSkill);
for (auto skill: aroundSpecifySkills)
{
result.Add(skill);
}
break;
}
case EEffectTargetType::SelfSkillType:
{
//筛选指定类型的技能
TArray<USkill*> SpecifySkills = GetSkillsByOwner(OwnerSkill->GetOwner());
//是否排除自身
if (!TargetSelector.bIncludeSelf)
{
SpecifySkills.Remove(OwnerSkill);
}
//全部还是指定数量随机
for (int i = SpecifySkills.Num() - 1; i >= 0; i--)
{
if (!SpecifySkills[i]->GetSkillData()->SkillTypes.Contains(TargetSelector.SkillType))
{
SpecifySkills.RemoveAt(i);
}
}
if (TargetSelector.bAll)
{
result.Append(SpecifySkills);
}
else
{
int TargetNum = FMath::Min(TargetSelector.MaxEffectTargetNum, SpecifySkills.Num());
for (int i = 0; i < TargetNum; i++)
{
int randomIndex = FMath::RandRange(0, SpecifySkills.Num() - 1);
result.Add(SpecifySkills[randomIndex]);
SpecifySkills.RemoveAt(randomIndex);
}
}
break;
}
case EEffectTargetType::TargetSkillType:
{
//筛选指定类型的技能
TArray<USkill*> SpecifySkills = GetSkillsByOwner(GetEnemyPawn(OwnerSkill->GetOwner()));
//是否排除自身
if (!TargetSelector.bIncludeSelf)
{
SpecifySkills.Remove(OwnerSkill);
}
for (int i = SpecifySkills.Num() - 1; i >= 0; i--)
{
if (!SpecifySkills[i]->GetSkillData()->SkillTypes.Contains(TargetSelector.SkillType))
{
SpecifySkills.RemoveAt(i);
}
}
if (TargetSelector.bAll)
{
result.Append(SpecifySkills);
}
else
{
int TargetNum = FMath::Min(TargetSelector.MaxEffectTargetNum, SpecifySkills.Num());
for (int i = 0; i < TargetNum; i++)
{
int randomIndex = FMath::RandRange(0, SpecifySkills.Num() - 1);
result.Add(SpecifySkills[randomIndex]);
SpecifySkills.RemoveAt(randomIndex);
}
}
break;
}
}
return result;
}