Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public override ICapabilityConfig Create()
.SetTarget<TransformTarget>()
.AddEffect<Hunger>(EffectType.Decrease)
.AddCondition<IsHolding<IEatable>>(Comparison.GreaterThanOrEqual, 1)
.AddCondition<Hunger>(Comparison.GreaterThanOrEqual, 30)
.AddCondition<Hunger, LowHunger>(Comparison.GreaterThanOrEqual)
.SetValidateConditions(false); // We don't need to validate conditions for this action, or it will stop when becoming below 80 hunger

builder.AddAction<GatherItemAction<Apple>>()
Expand All @@ -50,6 +50,8 @@ public override ICapabilityConfig Create()
builder.AddIsHoldingSensor<IEatable>();
builder.AddWorldSensor<HungerSensor>()
.SetKey<Hunger>();
builder.AddWorldSensor<LowHungerSensor>()
.SetKey<LowHunger>();

// Multi sensor
builder.AddMultiSensor<ItemSensor<IEatable>>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using CrashKonijn.Agent.Core;
using CrashKonijn.Goap.Core;
using CrashKonijn.Goap.Runtime;

namespace CrashKonijn.Goap.Demos.Complex.Sensors.World
{
public class LowHungerSensor : LocalWorldSensorBase
{
public override ISensorTimer Timer { get; } = SensorTimer.Once;

public override void Created()
{
}

public override void Update()
{
}

public override SenseValue Sense(IActionReceiver agent, IComponentReference references)
{
return 30;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using CrashKonijn.Goap.Runtime;

namespace CrashKonijn.Goap.Demos.Complex.WorldKeys
{
public class LowHunger : WorldKeyBase
{
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Package/Documentation/Config/Code.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ namespace CrashKonijn.Docs.GettingStarted.Capabilities
```
{% endcode %}

### Dynamic Conditions
Since v3.1 you can now add dynamic conditions!

{% code lineNumbers="true" %}
```csharp
builder.AddAction<EatAction>()
.AddCondition<Hunger, LowHunger>(Comparison.GreaterThanOrEqual);
```
{% endcode %}

### Callbacks
In v3 you can add a callback to your builder methods, giving you access to the instance of each class. This allows you to set extra data.

Expand Down
7 changes: 7 additions & 0 deletions Package/Documentation/upgrade/upgrade-guide-3.0-3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ public interface IGoapInjector

## New Features

### You can now make dynamic conditions (code only)!

```csharp
builder.AddAction<EatAction>()
.AddCondition<Hunger, LowHunger>(Comparison.GreaterThanOrEqual);
```

### AgenTypeFactory and CapabilityFactory can now be injected
You can now inject into `AgentTypeFactoryBase` and `CapabilityFactoryBase` classes, similar to other actions, goals and sensors.

Expand Down
8 changes: 8 additions & 0 deletions Package/Editor/CrashKonijn.Goap.Editor/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,13 @@ public static float GetCost(this INode node, IGoapActionProvider provider)

return 0;
}

public static int GetAmount(this ICondition condition)
{
if (condition is IValueCondition serializableCondition)
return serializableCondition.Amount;

return 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,28 @@ private string GetText(ICondition condition)
{
var suffix = this.GetSuffix(condition);

return $"{condition.WorldKey.Name} {this.GetText(condition.Comparison)} {condition.Amount} {suffix}";
return $"{condition.WorldKey.Name} {this.GetText(condition.Comparison)} {GetValueText(condition)} {suffix}";
}

private string GetValueText(ICondition condition)
{
if (condition is IValueCondition valueCondition)
return valueCondition.Amount.ToString();

if (condition is IReferenceCondition referenceCondition)
{
if (!Application.isPlaying)
return referenceCondition.ValueKey.Name;

if (this.values.SelectedObject is not IMonoGoapActionProvider agent)
return referenceCondition.ValueKey.Name;

var (exists, value) = agent.WorldData.GetWorldValue(referenceCondition.ValueKey);

return $"{value} ({referenceCondition.ValueKey.Name})";
}

return "";
}

private string GetSuffix(ICondition condition)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void Upgrade(CapabilityConfigScriptable capabilityScriptable)
Name = x.WorldKey.Name
},
comparison = x.Comparison,
amount = x.Amount
amount = x.GetAmount()
}).ToList()
});
}
Expand All @@ -152,7 +152,7 @@ private void Upgrade(CapabilityConfigScriptable capabilityScriptable)
Name = x.WorldKey.Name
},
comparison = x.Comparison,
amount = x.Amount
amount = x.GetAmount()
}).ToList(),
effects = actionConfig.Effects.Select(x => new CapabilityEffect
{
Expand Down
14 changes: 12 additions & 2 deletions Package/Runtime/CrashKonijn.Goap.Core/Interfaces/IActionBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using System;
using CrashKonijn.Agent.Core;
using CrashKonijn.Goap.Core;

namespace CrashKonijn.Goap.Runtime
namespace CrashKonijn.Goap.Core
{
public interface IActionBuilder<T> where T : IAction
{
Expand Down Expand Up @@ -69,6 +68,17 @@ IActionBuilder<T> SetTarget<TTargetKey>()
IActionBuilder<T> AddCondition<TWorldKey>(Comparison comparison, int amount)
where TWorldKey : IWorldKey;

/// <summary>
/// Adds a reference condition to the action.
/// </summary>
/// <typeparam name="TWorldKey">The type of the world key.</typeparam>
/// <typeparam name="TValueKey">The type of the value world key reference.</typeparam>
/// <param name="comparison">The comparison type.</param>
/// <returns>The current instance of <see cref="GoalBuilder{T}" />.</returns>
IActionBuilder<T> AddCondition<TWorldKey, TValueKey>(Comparison comparison)
where TWorldKey : IWorldKey
where TValueKey : IWorldKey;

IActionBuilder<T> AddEffect<TWorldKey>(bool increase)
where TWorldKey : IWorldKey;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ public interface ICondition
{
public IWorldKey WorldKey { get; }
public Comparison Comparison { get; }
}

public interface IValueCondition : ICondition
{
public int Amount { get; }
}

public interface IReferenceCondition : ICondition
{
public IWorldKey ValueKey { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public interface IWorldData
void SetTarget<TKey>(ITarget target) where TKey : ITargetKey;
bool IsTrue<TWorldKey>(Comparison comparison, int value);
bool IsTrue(IWorldKey worldKey, Comparison comparison, int value);
bool IsTrue(IWorldKey worldKey, Comparison comparison, IWorldKey valueKey);
(bool Exists, int Value) GetWorldValue<TKey>(TKey worldKey) where TKey : IWorldKey;
(bool Exists, int Value) GetWorldValue(Type worldKey);
ITarget GetTargetValue(Type targetKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public IActionBuilder<T> SetMoveMode(ActionMoveMode moveMode)
public IActionBuilder<T> AddCondition<TWorldKey>(Comparison comparison, int amount)
where TWorldKey : IWorldKey
{
this.conditions.Add(new Condition
this.conditions.Add(new ValueCondition
{
WorldKey = this.worldKeyBuilder.GetKey<TWorldKey>(),
Comparison = comparison,
Expand All @@ -116,6 +116,21 @@ public IActionBuilder<T> AddCondition<TWorldKey>(Comparison comparison, int amou

return this;
}

/// <summary>
/// Adds a reference condition to the action.
/// </summary>
/// <typeparam name="TWorldKey">The type of the world key.</typeparam>
/// <typeparam name="TValueKey">The type of the value world key reference.</typeparam>
/// <param name="comparison">The comparison type.</param>
/// <returns>The current instance of <see cref="GoalBuilder{T}" />.</returns>
public IActionBuilder<T> AddCondition<TWorldKey, TValueKey>(Comparison comparison)
where TWorldKey : IWorldKey
where TValueKey : IWorldKey
{
this.conditions.Add(new ReferenceCondition(this.worldKeyBuilder.GetKey<TWorldKey>(), comparison, this.worldKeyBuilder.GetKey<TValueKey>()));
return this;
}

[Obsolete("Use `AddEffect<TWorldKey>(EffectType type)` instead.")]
public IActionBuilder<T> AddEffect<TWorldKey>(bool increase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public IGoalBuilder<T> SetBaseCost(float baseCost)
}

/// <summary>
/// Adds a condition to the goal.
/// Adds a value condition to the goal.
/// </summary>
/// <typeparam name="TWorldKey">The type of the world key.</typeparam>
/// <param name="comparison">The comparison type.</param>
Expand All @@ -31,7 +31,22 @@ public IGoalBuilder<T> SetBaseCost(float baseCost)
public IGoalBuilder<T> AddCondition<TWorldKey>(Comparison comparison, int amount)
where TWorldKey : IWorldKey
{
this.conditions.Add(new Condition(this.worldKeyBuilder.GetKey<TWorldKey>(), comparison, amount));
this.conditions.Add(new ValueCondition(this.worldKeyBuilder.GetKey<TWorldKey>(), comparison, amount));
return this;
}

/// <summary>
/// Adds a reference condition to the goal.
/// </summary>
/// <typeparam name="TWorldKey">The type of the world key.</typeparam>
/// <typeparam name="TValueKey">The type of the value world key reference.</typeparam>
/// <param name="comparison">The comparison type.</param>
/// <returns>The current instance of <see cref="GoalBuilder{T}" />.</returns>
public GoalBuilder<T> AddCondition<TWorldKey, TValueKey>(Comparison comparison)
where TWorldKey : IWorldKey
where TValueKey : IWorldKey
{
this.conditions.Add(new ReferenceCondition(this.worldKeyBuilder.GetKey<TWorldKey>(), comparison, this.worldKeyBuilder.GetKey<TValueKey>()));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using CrashKonijn.Goap.Core;

namespace CrashKonijn.Goap.Runtime
{
public class ReferenceCondition : IReferenceCondition
{
public IWorldKey WorldKey { get; set; }
public Comparison Comparison { get; set; }
public IWorldKey ValueKey { get; set; }

public ReferenceCondition()
{
}

public ReferenceCondition(IWorldKey worldKey, Comparison comparison, IWorldKey valueKey)
{
this.WorldKey = worldKey;
this.Comparison = comparison;
this.ValueKey = valueKey;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ private SensorSet CreateSet(IGoapAction action)
foreach (var condition in action.Conditions)
{
set.Keys.Add(condition.WorldKey.GetType());

if (condition is IReferenceCondition referenceCondition)
set.Keys.Add(referenceCondition.ValueKey.GetType());
}

foreach (var key in set.Keys)
Expand Down Expand Up @@ -239,6 +242,17 @@ private SensorSet CreateSet(INode node)
{
set.AddSensor(sensor);
}

if (condition is IReferenceCondition referenceCondition)
{
var referenceKey = referenceCondition.ValueKey.GetType();
set.Keys.Add(referenceKey);

if (this.sensors.TryGetValue(referenceKey, out var referenceSensor))
{
set.AddSensor(referenceSensor);
}
}
}

foreach (var action in actions.Distinct())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

namespace CrashKonijn.Goap.Runtime
{
public class Condition : ICondition
public class ValueCondition : IValueCondition
{
public IWorldKey WorldKey { get; set; }
public Comparison Comparison { get; set; }
public int Amount { get; set; }

public Condition()
public ValueCondition()
{
}

public Condition(IWorldKey worldKey, Comparison comparison, int amount)
public ValueCondition(IWorldKey worldKey, Comparison comparison, int amount)
{
this.WorldKey = worldKey;
this.Comparison = comparison;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
using CrashKonijn.Goap.Core;
using System;
using CrashKonijn.Goap.Core;

namespace CrashKonijn.Goap.Runtime
{
public class ConditionObserver : ConditionObserverBase
{
public override bool IsMet(ICondition condition)
{
if (condition is IValueCondition valueCondition)
return IsMet(valueCondition);

if (condition is IReferenceCondition referenceCondition)
return IsMet(referenceCondition);

throw new ArgumentException($"Unknown condition type: {condition.GetType()}");
}

private bool IsMet(IValueCondition condition)
{
return this.WorldData.IsTrue(condition.WorldKey, condition.Comparison, condition.Amount);
}

private bool IsMet(IReferenceCondition condition)
{
return this.WorldData.IsTrue(condition.WorldKey, condition.Comparison, condition.ValueKey);
}
}
}
Loading