// Fill out your copyright notice in the Description page of Project Settings. #include "SkillTrigger.h" #include "Skill.h" #include "SkillManager.h" #include "ProjectFish/PawnWithSkill.h" void USkillTrigger::Init_Implementation(FSkillContext context, const FPassiveTriggerConfig& InPassiveTriggerConfig, const FAuraTriggerConfig& InAuraTriggerConfig) { SkillContext = context; PassiveTriggerConfig = InPassiveTriggerConfig; AuraTriggerConfig = InAuraTriggerConfig; InitConditionTriggers(); } void USkillTrigger::OnTrigger() { bTriggered = true; SkillContext.OwnerSkill->ExecuteSkill(); } void USkillTrigger::InitConditionTriggers() { if (SkillContext.OwnerSkill->GetSkillData()->triggerType == ESkillTriggerType::PassiveSkill) InitPassiveConditionTriggers(); else { InitAuraConditionTriggers(); } } void USkillTrigger::OnSkillExecute(const FString& SkillName) { OnTrigger(); } void USkillTrigger::InitPassiveConditionTriggers() { EEffectTargetType targetType = PassiveTriggerConfig.Target.SelecterType; switch (PassiveTriggerConfig.Condition) { case EPassiveTriggerCondition::ItemTriggered: { if (targetType !=EEffectTargetType::Self && targetType !=EEffectTargetType::Target) { TArray PawnSkills = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (auto Object : PawnSkills) { USkill* Skill = Cast(Object); if (Skill != SkillContext.OwnerSkill) Skill->OnSkillExecute.AddDynamic(this, &USkillTrigger::OnSkillExecute); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EPassiveTriggerCondition::DealDamage: { //造成伤害时触发 if (targetType !=EEffectTargetType::Self && targetType !=EEffectTargetType::Target) { //监测哪个角色受到了伤害 bool enemyMakeDamage = (targetType == EEffectTargetType::TargetSkill || targetType == EEffectTargetType::TargetSkillType); APawnWithSkill* ReceiveDamagePawn = enemyMakeDamage ? SkillContext.OwnerSkill->GetOwner() : SkillContext.SkillManager->GetEnemyPawn(SkillContext.OwnerSkill->GetOwner()); ReceiveDamagePawn->OnReceiveDamage.AddLambda([this](UObject* Source) { //UE_LOG(LogTemp, Error, TEXT("receive damge source = %s"), *Source->GetName()); APawnWithSkill* DamgePawn = nullptr; if (Source->GetClass() == USkill::StaticClass()) { DamgePawn = Cast(Source)->GetOwner(); } else if (Source->GetClass() == APawnWithSkill::StaticClass()) { DamgePawn = Cast(Source); } if (Source != SkillContext.OwnerSkill && DamgePawn != SkillContext.OwnerSkill->GetOwner() ) OnTrigger(); }); } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EPassiveTriggerCondition::SkillDurabilityDecrease: { //物品耐久度减少触发 if (targetType !=EEffectTargetType::Self && targetType !=EEffectTargetType::Target) { // //目标技能iD // FGuid TriggerSkillID = PassiveTriggerConfig.SpecificSkillID; // //目标pawn // APawnWithSkill* TargetPawn = targetType == EEffectTargetType::SelfSpecificItem ? SkillContext.OwnerSkill->GetOwner(): // SkillContext.SkillManager->GetEnemyPawn( SkillContext.OwnerSkill->GetOwner()); // // TArray SpecificSkills = SkillContext.SkillManager->GetSkillsByOwnerAndID(TargetPawn, TriggerSkillID); TArray PawnSkills = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : PawnSkills) { USkill* Skill = Cast(Object); Skill->OnSkillEnduranceChange.AddLambda([this](int32 EnduranceOffset) { if (EnduranceOffset < 0) OnTrigger(); }); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EPassiveTriggerCondition::SkillDurabilityRestore: { //物品耐久度恢复触发 if (targetType !=EEffectTargetType::Self && targetType !=EEffectTargetType::Target) { // //目标技能iD // FGuid TriggerSkillID = PassiveTriggerConfig.SpecificSkillID; // //目标pawn // APawnWithSkill* TargetPawn = targetType == EEffectTargetType::SelfSpecificItem ? SkillContext.OwnerSkill->GetOwner(): // SkillContext.SkillManager->GetEnemyPawn( SkillContext.OwnerSkill->GetOwner()); // // TArray SpecificSkills = SkillContext.SkillManager->GetSkillsByOwnerAndID(TargetPawn, TriggerSkillID); TArray PawnSkills = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : PawnSkills) { USkill* Skill = Cast(Object); Skill->OnSkillEnduranceChange.AddLambda([this](int32 EnduranceOffset) { if (EnduranceOffset > 0) OnTrigger(); }); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EPassiveTriggerCondition::HealthFirstBelowPercent: { //目标生命值低于x时触发 if (targetType == EEffectTargetType::Self || targetType == EEffectTargetType::Target) { // //目标pawn // APawnWithSkill* TargetPawn = targetType == EEffectTargetType::Self ? SkillContext.OwnerSkill->GetOwner(): // SkillContext.SkillManager->GetEnemyPawn( SkillContext.OwnerSkill->GetOwner()); TArray PawnSkills = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : PawnSkills) { APawnWithSkill* TargetPawn = Cast(Object); //绑定生命值发生变化 TargetPawn->OnReceiveDamage.AddLambda([this, TargetPawn](UObject* Source) { if (!this->bTriggered && TargetPawn->CurrentEndurance /TargetPawn ->MaxEndurance < this->PassiveTriggerConfig.PercentageValue) { OnTrigger(); } }); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } default: break; } } void USkillTrigger::InitAuraConditionTriggers() { EEffectTargetType targetType = PassiveTriggerConfig.Target.SelecterType; switch (AuraTriggerConfig.Condition) { case EAuraTriggerCondition::None: { OnTrigger(); break; } case EAuraTriggerCondition::HealthBelowPercent: { if (targetType == EEffectTargetType::Self || targetType == EEffectTargetType::Target) { // //目标pawn // APawnWithSkill* TargetPawn = AuraTriggerConfig.Target == EAuraTriggerTarget::Self ? SkillContext.OwnerSkill->GetOwner(): // SkillContext.SkillManager->GetEnemyPawn( SkillContext.OwnerSkill->GetOwner()); TArray Pawn = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : Pawn) { APawnWithSkill* TargetPawn = Cast(Object); //初始检测 if (!this->bTriggered && TargetPawn->CurrentEndurance /TargetPawn ->MaxEndurance < this->AuraTriggerConfig.PercentageValue) { OnTrigger(); } //动态检测 TargetPawn->OnReceiveDamage.AddLambda([this, TargetPawn](UObject* Source) { if (!this->bTriggered && TargetPawn->CurrentEndurance /TargetPawn ->MaxEndurance < this->AuraTriggerConfig.PercentageValue) { OnTrigger(); } }); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EAuraTriggerCondition::HealthAbovePercent: { if (targetType == EEffectTargetType::Self || targetType == EEffectTargetType::Target) { // //目标pawn // APawnWithSkill* TargetPawn = AuraTriggerConfig.Target == EAuraTriggerTarget::Self ? SkillContext.OwnerSkill->GetOwner(): // SkillContext.SkillManager->GetEnemyPawn( SkillContext.OwnerSkill->GetOwner()); TArray Pawn = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : Pawn) { APawnWithSkill* TargetPawn = Cast(Object); //初始检测 if (!this->bTriggered && TargetPawn->CurrentEndurance /TargetPawn ->MaxEndurance < this->AuraTriggerConfig.PercentageValue) { OnTrigger(); } //动态检测 TargetPawn->OnReceiveDamage.AddLambda([this, TargetPawn](UObject* Source) { if (!this->bTriggered && TargetPawn->CurrentEndurance /TargetPawn ->MaxEndurance > this->AuraTriggerConfig.PercentageValue) { OnTrigger(); } }); } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EAuraTriggerCondition::EquipmentCountNotMoreThan: { if (targetType == EEffectTargetType::Self || targetType == EEffectTargetType::Target) { TArray Pawn = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : Pawn) { APawnWithSkill* TargetPawn = Cast(Object); if (!this->bTriggered && SkillContext.SkillManager->GetSkillsByOwner(TargetPawn).Num() <= this->AuraTriggerConfig.CountValue) { OnTrigger(); } } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } case EAuraTriggerCondition::EquipmentCountNotLessThan: { if (targetType == EEffectTargetType::Self || targetType == EEffectTargetType::Target) { TArray Pawn = SkillContext.SkillManager->GetTargetsBySelector(SkillContext.OwnerSkill, PassiveTriggerConfig.Target); for (UObject* Object : Pawn) { APawnWithSkill* TargetPawn = Cast(Object); if (!this->bTriggered && SkillContext.SkillManager->GetSkillsByOwner(TargetPawn).Num() >= this->AuraTriggerConfig.CountValue) { OnTrigger(); } } } else { UE_LOG(LogTemp, Error, TEXT("Target 与 Condition 不匹配")); } break; } default: break; } }