Added Healing Action & Resource Uncertainty

This commit is contained in:
Philip W 2023-03-23 02:55:32 +00:00
parent 98a9f73095
commit 3a1a2a106d
7 changed files with 89 additions and 14 deletions

View File

@ -5,7 +5,7 @@
void UCOMBO_AAA::Init()
{
ActionCost = 1.0f;
ActionCost = 1.5f;
ActionName = "AAA";
PreConditions.Add("AzosResource", 3);
Effects.Add("PlayerHealth", 20);

View File

@ -0,0 +1,21 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "COMBO_IIA.h"
void UCOMBO_IIA::Init()
{
ActionCost = 0.5f;
ActionName = "Heal";
PreConditions.Add("AzosResource", 1);
PreConditions.Add("IroquoidResource", 2);
PreConditions.Add("EnemyHealth", 50);
Effects.Add("EnemyHealth", -10);
Effects.Add("AzosResource", 1);
Effects.Add("IroquoidResource", 2);
}
TMap<FString, int> UCOMBO_IIA::Perform(UWorldState* WorldState)
{
return Effects;
}

View File

@ -0,0 +1,20 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "../GOAPAction.h"
#include "COMBO_IIA.generated.h"
/**
*
*/
UCLASS()
class COMP250_1_2101327_AI_API UCOMBO_IIA : public UGOAPAction
{
GENERATED_BODY()
public:
virtual void Init() override;
virtual TMap<FString, int> Perform(UWorldState* WorldState) override;
};

View File

@ -5,7 +5,7 @@
void UCOMBO_III::Init()
{
ActionCost = 1.0f;
ActionCost = 1.5f;
ActionName = "III";
PreConditions.Add("IroquoidResource", 3);
Effects.Add("PlayerHealth", 20);

View File

@ -12,7 +12,11 @@ bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
{
for (TPair<FString, int> PreCondition : PreConditions)
{
if (WorldState->State.Contains(PreCondition.Key))
if (PreCondition.Key == "PlayerHealth" || PreCondition.Key == "EnemyHealth")
{
if (WorldState->State[PreCondition.Key] >= PreCondition.Value) return false;
}
else if (WorldState->State.Contains(PreCondition.Key))
{
if (WorldState->State[PreCondition.Key] < PreCondition.Value) return false;
}
@ -41,9 +45,19 @@ UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
/**
* @brief Performs the action
* @return A map of the effects of the action
* @return A map of the effects of the action or
* an empty map if the enemy health is less than or equal to 50 to force a re-plan or
* if the world state falls short of the preconditions to force a re-plan
*/
TMap<FString, int> UGOAPAction::Perform()
TMap<FString, int> UGOAPAction::Perform(UWorldState* WorldState)
{
if (WorldState->State["EnemyHealth"] <= 50)
{
return TMap<FString, int>();
}
if (!CheckPreConditions(WorldState))
{
return TMap<FString, int>();
}
return Effects;
}

View File

@ -24,7 +24,7 @@ public:
UFUNCTION()
UWorldState* ApplyEffects(UWorldState* WorldState);
UFUNCTION()
virtual TMap<FString, int> Perform();
virtual TMap<FString, int> Perform(UWorldState* WorldState);
UPROPERTY()
TMap<FString, int> PreConditions;

View File

@ -267,14 +267,14 @@ void ATurnBaseCombatV2::RevertActionPoints()
void ATurnBaseCombatV2::DamagePlayer(int Damage, FString DamageType)
{
*PlayerHealth -= FMath::Clamp(Damage, 0, 100);
*PlayerHealth -= FMath::Clamp(Damage, -10, 100);
UpdateProgressBars();
AddBattleLogMessage("Player was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
}
void ATurnBaseCombatV2::DamageEnemy(int Damage, FString DamageType)
{
*EnemyHealth -= FMath::Clamp(Damage, 0, 100);
*EnemyHealth -= FMath::Clamp(Damage, -10, 100);
UpdateProgressBars();
AddBattleLogMessage("Enemy was damaged for " + FString::FromInt(Damage) + " HP by " + DamageType + ".");
}
@ -471,26 +471,44 @@ void ATurnBaseCombatV2::EnemyTurn()
{
if (EnemyActionPlan.Num() > 0)
{
TMap<FString, int> ActionEffects = EnemyActionPlan[0]->Perform();
TMap<FString, int> ActionEffects = EnemyActionPlan[0]->Perform(GetWorldState());
if (ActionEffects.IsEmpty())
{
EnemyActionPlan = EnemyGOAPAgent->Plan(GetWorldState(), EnemyGOAPAgent->Goals);
ClearActionPlanWidget();
UpdateActionPlanWidget();
OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));
ToggleButtons();
return;
}
if (ActionEffects.Contains("PlayerHealth"))
{
DamagePlayer(ActionEffects["PlayerHealth"], EnemyActionPlan[0]->ActionName);
}
else
{
DamageEnemy(ActionEffects["EnemyHealth"], EnemyActionPlan[0]->ActionName);
}
for (const TTuple<FString, int> Effect : ActionEffects)
{
if (Effect.Key == "ProbertiumResource")
{
EnemyProbertiumResource -= Effect.Value;
EnemyProbertiumResource -= FMath::RandRange(Effect.Value - 1, Effect.Value + 1);
}
else if (Effect.Key == "EisResource")
{
EnemyEisResource -= Effect.Value;
EnemyEisResource -= FMath::RandRange(Effect.Value - 1, Effect.Value + 1);
}
else if (Effect.Key == "AzosResource")
{
EnemyAzosResource -= Effect.Value;
EnemyAzosResource -= FMath::RandRange(Effect.Value - 1, Effect.Value + 1);
}
else if (Effect.Key == "IroquoidResource")
{
EnemyIroquoidResource -= Effect.Value;
EnemyIroquoidResource -= FMath::RandRange(Effect.Value - 1, Effect.Value + 1);
}
}
@ -500,6 +518,8 @@ void ATurnBaseCombatV2::EnemyTurn()
else
{
EnemyActionPlan = EnemyGOAPAgent->Plan(GetWorldState(), EnemyGOAPAgent->Goals);
ClearActionPlanWidget();
UpdateActionPlanWidget();
}
OnEnemyTurn.Broadcast(EnemyActor, PlayerActor);
TurnIndicatorTextBlock->SetText(FText::FromString("Player Turn"));