コード例 #1
0
bool MeleeCombatTask::Perform(Subsystem& subsystem)
{
	DM_LOG(LC_AI, LT_INFO)LOGSTRING("Melee Combat Task performing.\r");

	idAI* ownerEnt = _owner.GetEntity();
	assert(ownerEnt != NULL);

	idActor* enemy = _enemy.GetEntity();
	if ( ( enemy == NULL ) || enemy->IsKnockedOut() || ( enemy->health <= 0 ) )
	{
		DM_LOG(LC_AI, LT_DEBUG)LOGSTRING("No enemy, terminating task!\r");
		return true; // terminate me
	}

	// Perform the task according to the current action
	EMeleeActState actState = ownerEnt->m_MeleeStatus.m_ActionState;

	switch (actState)
	{
	case MELEEACTION_READY:
		PerformReady(ownerEnt);
		break;
	case MELEEACTION_ATTACK:
		PerformAttack(ownerEnt);
		break;
	case MELEEACTION_PARRY:
		PerformParry(ownerEnt);
		break;
	default:
		PerformReady(ownerEnt);
	};
	
	return false; // not finished yet
}
コード例 #2
0
void AZombieShooterCharacter::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	CalculateFacing();

	// Determine if the character should perform an attack
	AttackCooldownRemaining -= DeltaSeconds;
	if (bAttacking){
		PerformAttack();
	}
}
コード例 #3
0
void AMonsterAIController::PhysicalAttackPriority(ACombatController* &Con)
{
	int32 RandomInt = 0;

	// First Things First. If the warrior has an ability that is a Self-Buff, he uses it.
	if (MyMonster->AI_Archetype == EAIArchetypes::Warrior)
	{
		CastSelfBuff(Con);
		if (bHasActionBeenDecidedYet)return;
	}

	// If not, then we proceed to check our HP.
	if ((MyMonster->MaxHealth - MyMonster->CurrentHealth / MyMonster->MaxHealth) >= 0.75f)
	{
		// If our HP is low, we check all our enemies that are not currently defending, and are also low on hp to perform an attack of opportunity.
		TArray<int32> IndexesOfPossibleVictims;
		for (size_t i = 0; i < 3; i++)
		{
			if (!Con->PartyA[i]->bIsDead)
			{
				if (Con->PartyA[i]->bIsDefending)
				{
					if ((Con->PartyA[i]->MaxHealth - Con->PartyA[i]->CurrentHealth / Con->PartyA[i]->MaxHealth) >= 0.9f)
					{
						//Even if they defend, if they have less than 10%, we may have a chance.
						IndexesOfPossibleVictims.Add(Con->PartyA[i]->MonsterID);
					}
				}
				else
				{
					if ((Con->PartyA[i]->MaxHealth - Con->PartyA[i]->CurrentHealth / Con->PartyA[i]->MaxHealth) >= 0.8f)
					{
						IndexesOfPossibleVictims.Add(Con->PartyA[i]->MonsterID);
					}
				}
			}
		}


		//Prioritize the enemies based on:
		if (IndexesOfPossibleVictims.Num() > 0)
		{
			RandomInt = FMath::FRandRange(1, 100);
			if (RandomInt <= 40) // Lowest Quantitative Health.
			{
				int32 LowLimHP = Con->PartyA[IndexesOfPossibleVictims[0]]->CurrentHealth;
				int32 IndexOfFinalTarget = 0;
				for (size_t i = 0; i < IndexesOfPossibleVictims.Num(); i++)
				{
					for (size_t j = 0; j < Con->PartyA.Num(); j++)
					{
						if (Con->PartyA[j]->MonsterID == IndexesOfPossibleVictims[i])
						{
							if (Con->PartyA[j]->CurrentHealth < LowLimHP)
							{
								LowLimHP = Con->PartyA[j]->CurrentHealth;
								IndexOfFinalTarget = IndexesOfPossibleVictims[i];
							}
						}
					}
					
				}

				PerformAttack(Con, IndexOfFinalTarget);
				if (bHasActionBeenDecidedYet)return;
			}
			else if (RandomInt <= 75) // Lowest Defense
			{
				int32 LowLimDEF = Con->PartyA[IndexesOfPossibleVictims[0]]->GetDefense();
				int32 IndexOfFinalTarget = 0;
				for (size_t i = 0; i < IndexesOfPossibleVictims.Num(); i++)
				{
					for (size_t j = 0; j < Con->PartyA.Num(); j++)
					{
						if (Con->PartyA[j]->MonsterID == IndexesOfPossibleVictims[i])
						{
							if (Con->PartyA[j]->GetDefense() < LowLimDEF)
							{
								LowLimDEF = Con->PartyA[j]->GetDefense();
								IndexOfFinalTarget = IndexesOfPossibleVictims[i];
							}
						}
					}
				}
				PerformAttack(Con, IndexOfFinalTarget);
				if (bHasActionBeenDecidedYet)return;
			}
			else // Random.
			{
				PerformAttack(Con, IndexesOfPossibleVictims[FMath::RandRange(0, IndexesOfPossibleVictims.Num() - 1)]);
				if (bHasActionBeenDecidedYet)return;
			}
		}
		else
		{
			// No monsters selected. Defend instead.

			PerformDefend(Con);
			if (bHasActionBeenDecidedYet)return;
		}
	}
	else
	{
		// If our HP is NOT low, we attack based on the prioritization made above.
		RandomInt = FMath::FRandRange(1, 100);
		if (RandomInt < 80 || MyMonster->AI_Archetype != EAIArchetypes::Warrior)
		{
			TArray<int32> IndexesOfPossibleVictims;
			for (size_t i = 0; i < 3; i++)
			{
				if (!Con->PartyA[i]->bIsDead)
				{
					if (Con->PartyA[i]->bIsDefending)
					{
						if ((Con->PartyA[i]->MaxHealth - Con->PartyA[i]->CurrentHealth / Con->PartyA[i]->MaxHealth) >= 0.8f)
						{
							//Even if they defend, if they have less than 10%, we may have a chance.
							IndexesOfPossibleVictims.Add(Con->PartyA[i]->MonsterID);
						}
					}
					else
					{
						IndexesOfPossibleVictims.Add(Con->PartyA[i]->MonsterID);
					}
				}
			}


			//Prioritize the enemies based on:
			if (IndexesOfPossibleVictims.Num() > 0)
			{
				RandomInt = FMath::FRandRange(1, 100);
				if (RandomInt <= 40) // Lowest Quantitative Health.
				{
					int32 LowLimHP = Con->PartyA[IndexesOfPossibleVictims[0]]->CurrentHealth;
					int32 IndexOfFinalTarget = 0;
					for (size_t i = 0; i < IndexesOfPossibleVictims.Num(); i++)
					{
						for (size_t j = 0; j < Con->PartyA.Num(); j++)
						{
							if (Con->PartyA[j]->MonsterID == IndexesOfPossibleVictims[i])
							{
								if (Con->PartyA[j]->CurrentHealth < LowLimHP)
								{
									LowLimHP = Con->PartyA[j]->CurrentHealth;
									IndexOfFinalTarget = IndexesOfPossibleVictims[i];
								}
							}
						}
					}

					PerformAttack(Con, IndexOfFinalTarget);
					if (bHasActionBeenDecidedYet)return;
				}
				else if (RandomInt <= 75) // Lowest Defense
				{
					int32 LowLimDEF = Con->PartyA[IndexesOfPossibleVictims[0]]->GetDefense();
					int32 IndexOfFinalTarget = 0;
					for (size_t i = 0; i < IndexesOfPossibleVictims.Num(); i++)
					{
						for (size_t j = 0; j < Con->PartyA.Num(); j++)
						{
							if (Con->PartyA[j]->MonsterID == IndexesOfPossibleVictims[i])
							{
								if (Con->PartyA[j]->GetDefense() < LowLimDEF)
								{
									LowLimDEF = Con->PartyA[j]->GetDefense();
									IndexOfFinalTarget = IndexesOfPossibleVictims[i];
								}
							}
						}
					}
					PerformAttack(Con, IndexOfFinalTarget);
					if (bHasActionBeenDecidedYet)return;
				}
				else // Random.
				{
					PerformAttack(Con, IndexesOfPossibleVictims[FMath::RandRange(0, IndexesOfPossibleVictims.Num() - 1)]);
					if (bHasActionBeenDecidedYet)return;
				}
			}
			else
			{
				// No monsters selected. Defend instead.
				PerformDefend(Con);
				if (bHasActionBeenDecidedYet)return;
			}
		}
		else
		{
			DecideForSpellToCast(Con);
			if (bHasActionBeenDecidedYet)return;
		}
	}
}