241 lines
6.3 KiB
C++
241 lines
6.3 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
||
|
||
|
||
#include "Skill.h"
|
||
|
||
#include "InputTriggers.h"
|
||
#include "SkillTrigger.h"
|
||
#include "SkillEffects/SkillEffect_Charge.h"
|
||
#include "SkillEffects/SkillEffect_Damage.h"
|
||
#include "SkillEffects/SkillEffect_DamageReduce.h"
|
||
#include "SkillEffects/SkillEffect_EnhanceFishRod.h"
|
||
#include "SkillEffects/SkillEffect_EnhanceSkill.h"
|
||
#include "SkillEffects/SkillEffect_Heal.h"
|
||
#include "SkillEffects/SkillEffect_ModifyCD.h"
|
||
#include "SkillEffects/SkillEffect_ModifySpeed.h"
|
||
#include "SkillEffects/SkillEffect_SER.h"
|
||
|
||
|
||
void USkill::InitSkill(class APawnWithSkill* owner, USkillManager* skillManager, const FPlacedSkillInfo& PlacedSkill)
|
||
{
|
||
this->Owner = owner;
|
||
this->SkillManager = skillManager;
|
||
this->SkillData = PlacedSkill.SkillAsset;
|
||
this->BagPosition = FIntPoint(PlacedSkill.PositionX, PlacedSkill.PositionY);
|
||
this->RemainingTime = SkillData->CD;
|
||
this->RemainingEndurance = SkillData->Endurance;
|
||
for (auto effectData: SkillData->SkillEffects)
|
||
{
|
||
USkillEffect* skillEffect = nullptr ;
|
||
switch (effectData.EffectType)
|
||
{
|
||
case ESkillEffectType::Damage:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_Damage::StaticClass());
|
||
break;
|
||
case ESkillEffectType::Heal:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_Heal::StaticClass());
|
||
break;
|
||
case ESkillEffectType::ModifyCooldown:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_ModifyCD::StaticClass());
|
||
break;
|
||
case ESkillEffectType::Charge:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_Charge::StaticClass());
|
||
break;
|
||
case ESkillEffectType::ModifySpeed:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_ModifySpeed::StaticClass());
|
||
break;
|
||
case ESkillEffectType::SkillEnduranceRestore:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_SER::StaticClass());
|
||
break;
|
||
case ESkillEffectType::EnhanceFishRod:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_EnhanceFishRod::StaticClass());
|
||
break;
|
||
case ESkillEffectType::EnhanceSkill:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_EnhanceSkill::StaticClass());
|
||
break;
|
||
case ESkillEffectType::DamageReduce:
|
||
skillEffect = NewObject<USkillEffect>(this, USkillEffect_DamageReduce::StaticClass());
|
||
break;
|
||
default:
|
||
const UEnum* EnumPtr = StaticEnum<ESkillEffectType>();
|
||
UE_LOG(LogTemp, Error, TEXT("没有配置 %s类型的Skill Effect"), *EnumPtr->GetNameStringByValue(static_cast<int64>(effectData.EffectType)))
|
||
}
|
||
if (IsValid(skillEffect))
|
||
{
|
||
skillEffect->InitSkillEffect(this, effectData);
|
||
this->SkillEffects.Add(skillEffect);
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
void USkill::InitSkillTrigger()
|
||
{
|
||
switch (SkillData->triggerType)
|
||
{
|
||
case ESkillTriggerType::PassiveSkill:
|
||
{
|
||
USkillTrigger* SkillTrigger = NewObject<USkillTrigger>(this);
|
||
FSkillContext context;
|
||
context.OwnerSkill = this;
|
||
context.SkillManager = SkillManager;
|
||
SkillTrigger->Init(context, SkillData->PassiveTriggerConfig, SkillData->AuraTriggerConfig);
|
||
break;
|
||
}
|
||
|
||
case ESkillTriggerType::AuraSkill:
|
||
{
|
||
USkillTrigger* SkillTrigger = NewObject<USkillTrigger>(this);
|
||
FSkillContext context;
|
||
context.OwnerSkill = this;
|
||
context.SkillManager = SkillManager;
|
||
SkillTrigger->Init(context, SkillData->PassiveTriggerConfig, SkillData->AuraTriggerConfig);
|
||
}
|
||
|
||
// if (SkillData->AuraTriggerConfig.Condition != EAuraTriggerCondition::None)
|
||
// {
|
||
// USkillTrigger* SkillTrigger = NewObject<USkillTrigger>(this);
|
||
// FSkillContext context;
|
||
// context.OwnerSkill = this;
|
||
// context.SkillManager = SkillManager;
|
||
// SkillTrigger->Init(context, SkillData->PassiveTriggerConfig, SkillData->AuraTriggerConfig);
|
||
// }
|
||
// else
|
||
// {
|
||
// //UE_LOG(LogTemp, Warning, TEXT("没有Trigger的被动技能,直接触发"));
|
||
// ExecuteSkill();
|
||
// }
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
bool USkill::SkillTickAble()
|
||
{
|
||
//剩余次数无限制 或者 剩余次数大于0次并且拥有者没有被韧性眩晕
|
||
return (RemainingEndurance == -1 || RemainingEndurance >= 0 )
|
||
&& Owner->CurrentTenacity > 0 && SkillData->triggerType == ESkillTriggerType::ActiveSkill;
|
||
}
|
||
|
||
bool USkill::SkillExecuteAble()
|
||
{
|
||
return (RemainingEndurance == -1 || RemainingEndurance > 0 ) && RemainingTime <= 0;
|
||
}
|
||
|
||
FIntPoint USkill::GetSkillSize()
|
||
{
|
||
return GetSkillSizeValue(SkillData->SkillSize);
|
||
}
|
||
|
||
void USkill::TickSkill(float deltaTime)
|
||
{
|
||
if (SkillTickAble())
|
||
{
|
||
RemainingTime -= deltaTime * SkillData->Speed;
|
||
RemainingTime = FMath::Max(RemainingTime, 0);
|
||
}
|
||
|
||
if (SkillExecuteAble() )
|
||
{
|
||
ExecuteSkill();
|
||
}
|
||
// if (RemainingEndurance == 0)
|
||
// {
|
||
// FSkillContext context;
|
||
// context.OwnerSkill = this;
|
||
// context.SkillManager = SkillManager;
|
||
// for (auto Effect: SkillEffects)
|
||
// {
|
||
// Effect->EffectEnded(context);
|
||
// }
|
||
// }
|
||
}
|
||
|
||
void USkill::ExecuteSkill()
|
||
{
|
||
RemainingTime = 0;
|
||
if (RemainingEndurance >0)
|
||
{
|
||
ApplyRemainingEnduranceOffset(-1);
|
||
}
|
||
FSkillContext context;
|
||
context.OwnerSkill = this;
|
||
context.SkillManager = SkillManager;
|
||
for (auto Effect: SkillEffects)
|
||
{
|
||
Effect->Execute(context);
|
||
}
|
||
RemainingTime = SkillData->CD;
|
||
OnSkillExecute.Broadcast(SkillData->SkillName.ToString());
|
||
}
|
||
|
||
void USkill::CancelSkill()
|
||
{
|
||
FSkillContext context;
|
||
context.OwnerSkill = this;
|
||
context.SkillManager = SkillManager;
|
||
for (auto Effect: SkillEffects)
|
||
{
|
||
Effect->Cancel(context);
|
||
}
|
||
}
|
||
|
||
FString USkill::GetSkillName() const
|
||
{
|
||
return SkillData->SkillName.ToString();;
|
||
}
|
||
|
||
TObjectPtr<USkillAsset> USkill::GetSkillData()
|
||
{
|
||
return SkillData;
|
||
}
|
||
|
||
FIntPoint USkill::GetBagPos()
|
||
{
|
||
return BagPosition;
|
||
}
|
||
|
||
void USkill::SetSkillData(TObjectPtr<USkillAsset> data)
|
||
{
|
||
SkillData = data;
|
||
OnSkillUpdate.Broadcast();
|
||
}
|
||
|
||
void USkill::ApplyRemainingTimeOffset(int timeOffset)
|
||
{
|
||
this->RemainingTime += timeOffset;
|
||
}
|
||
|
||
void USkill::ApplyRemainingEnduranceOffset(int Offset)
|
||
{
|
||
if (SkillData->Endurance != -1)
|
||
{
|
||
RemainingEndurance = FMath::Clamp( RemainingEndurance + Offset, 0, SkillData->Endurance);
|
||
OnSkillEnduranceChange.Broadcast(Offset);
|
||
}
|
||
|
||
}
|
||
|
||
FTimerHandle TimerHandle;
|
||
|
||
void USkill::ApplySkillSpeed(float offset, float duration)
|
||
{
|
||
OnSkillSpeedChanged.Broadcast(offset < 0 ? true: false, duration);
|
||
GetSkillData()->Speed += offset;
|
||
GetWorld()->GetTimerManager().SetTimer(TimerHandle, [&]()
|
||
{
|
||
UE_LOG(LogTemp, Log, TEXT("取消CD充能效果!"));
|
||
GetSkillData()->Speed = 1;
|
||
|
||
}, duration, false); // 单次触发
|
||
}
|
||
|
||
|
||
class APawnWithSkill* USkill::GetOwner()
|
||
{
|
||
return Owner;
|
||
}
|