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() void UCOMBO_AAA::Init()
{ {
ActionCost = 1.0f; ActionCost = 1.5f;
ActionName = "AAA"; ActionName = "AAA";
PreConditions.Add("AzosResource", 3); PreConditions.Add("AzosResource", 3);
Effects.Add("PlayerHealth", 20); 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() void UCOMBO_III::Init()
{ {
ActionCost = 1.0f; ActionCost = 1.5f;
ActionName = "III"; ActionName = "III";
PreConditions.Add("IroquoidResource", 3); PreConditions.Add("IroquoidResource", 3);
Effects.Add("PlayerHealth", 20); Effects.Add("PlayerHealth", 20);

View File

@ -12,7 +12,11 @@ bool UGOAPAction::CheckPreConditions(UWorldState* WorldState)
{ {
for (TPair<FString, int> PreCondition : PreConditions) 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; if (WorldState->State[PreCondition.Key] < PreCondition.Value) return false;
} }
@ -41,9 +45,19 @@ UWorldState* UGOAPAction::ApplyEffects(UWorldState* WorldState)
/** /**
* @brief Performs the action * @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; return Effects;
} }

View File

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

View File

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