Attitude Solvers
Attitude Solvers encapsulates the logic used to determine what's the attitude between Faction Members.
Similar to the Faction Database, it's not an object used directly but instead, it's used by the Subsystem to determine the Attitude between Factions.
Since projects can have many different requirements to perform such evaluation, this object is very easy to extend. The framework provides a some classes worth mentioning:
- The
NinjaFactionAttitudeSolver
base class. - The
FactionSolver_SimpleAttitudeCheck
that simply determines attitude based on different factions and their configuration, both for the Default Attitudes and custom Attitudes provides via the Attitude Matrix. - The
FactionSolver_TargetReputation
that has a more elaborate strategy, based on an amount of reputation and multiple reputation tiers. We'll discuss this one in more detail in the Reputation section.
Faction Solver: Simple Attitude Check
The default Faction Solver will evaluate the Attitude based on a Source and Target Faction Data. Even though it's a very straightforward solver, it does a few different things with the Source and Target Faction Data.
Here's a diagram to represent its operation:
flowchart TD
A[Check Attitude] --> B{Is Same Faction?}
B --> |Yes| C[Attitude Towards Same Faction]
B --> |No| D{Has Custom Attitude?}
C --> G[Attitude Solved]
D --> |Yes| E[Specific Attitude for Target Faction]
D --> |No| F[Default Attitude Towards Other Factions]
E --> G[Attitude Solved]
F --> G[Attitude Solved]
Create a new Faction Attitude Solver
The base NinjaFactionAttitudeSolver
class will provide utility functions such as access to the Faction
Database and helper methods to retrieve the Faction Member Component and Main Faction from a target.
You can implement your Database using Blueprints or C++. Here's an example that will create a chaotic agent, that will always return a random attitude.
Create Attitude Solvers Blueprints using the Context Menu
In your Content Browser, you can right-click within your target folder and under the "Factions" category, there's an option to create the Faction Attitude Solver Blueprint!
#pragma once
#include "CoreMinimal.h"
#include "NinjaFactionAttitudeSolver.h"
#include "FactionSolver_CrazySolver.generated.h"
UCLASS(DisplayName = "Faction Database: Data Array")
class PLUGINLABS_API UFactionSolver_CrazySolver : public UNinjaFactionAttitudeSolver
{
GENERATED_BODY()
public:
// -- Begin Faction Attitude Solver implementation
virtual ETeamAttitude::Type SolveAttitude_Implementation(const AActor* Source, const AActor* Target) const override;
// -- End Faction Attitude Solver implementation
};
#include "FactionSolver_CrazySolver.h"
ETeamAttitude::Type UFactionSolver_CrazySolver::SolveAttitude_Implementation(const AActor* Source, const AActor* Target) const
{
// Yikes! o.O
return FMath::RandBool() ? ETeamAttitude::Friendly : ETeamAttitude::Hostile;
}
At this point, you would configure the new Attitude Solver Class in the Project Settings page. It's up to you to further experiment with that or continue using the default solver.
The SolveAttitude
Function is the only one that you must implement. But depending on what you are trying
to achieve, is worth knowing that there's a InitializeSolver
that can be used, to perform startup tasks.
If you override the initialization, make sure to call the super/parent implementation!
Next Steps
Now that we covered the Faction Attitude Solver object, you can decide if you'd prefer to move onto the Faction Membership section and start configuring your Faction Members, or if you want to know more about Attitude Solving and check the Reputation Section.