Refactor AI considerations (#1278)
Considerations are now instantiated under a manager and re-used between entities where they pass in their blackboard to get a score back. Also makes the API a bit nicer to use. Also some random cleanup. Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Inventory;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Inventory;
|
||||
using Content.Server.AI.Utility.Curves;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Combat;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
{
|
||||
@@ -37,15 +38,21 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
context.GetState<TargetEntityState>().SetValue(_entity);
|
||||
}
|
||||
|
||||
protected override Consideration[] Considerations { get; } = {
|
||||
new MeleeWeaponEquippedCon(
|
||||
new InverseBoolCurve()),
|
||||
new CanPutTargetInHandsCon(
|
||||
new BoolCurve()),
|
||||
new MeleeWeaponSpeedCon(
|
||||
new QuadraticCurve(1.0f, 0.5f, 0.0f, 0.0f)),
|
||||
new MeleeWeaponDamageCon(
|
||||
new QuadraticCurve(1.0f, 0.25f, 0.0f, 0.0f)),
|
||||
};
|
||||
protected override IReadOnlyCollection<Func<float>> GetConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<CanPutTargetInHandsCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.5f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponDamageCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.25f, 0.0f, 0.0f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Combat;
|
||||
@@ -7,7 +8,6 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.Utility.Curves;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Combat;
|
||||
@@ -15,6 +15,7 @@ using Content.Server.AI.WorldState.States.Inventory;
|
||||
using Content.Server.AI.WorldState.States.Movement;
|
||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
{
|
||||
@@ -30,16 +31,15 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
|
||||
public override void SetupOperators(Blackboard context)
|
||||
{
|
||||
var equipped = context.GetState<EquippedEntityState>().GetValue();
|
||||
MoveToEntityOperator moveOperator;
|
||||
var equipped = context.GetState<EquippedEntityState>().GetValue();
|
||||
if (equipped != null && equipped.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent))
|
||||
{
|
||||
moveOperator = new MoveToEntityOperator(Owner, _entity, meleeWeaponComponent.Range - 0.01f);
|
||||
}
|
||||
// I think it's possible for this to happen given planning is time-sliced?
|
||||
// TODO: At this point we should abort
|
||||
else
|
||||
{
|
||||
// TODO: Abort
|
||||
moveOperator = new MoveToEntityOperator(Owner, _entity);
|
||||
}
|
||||
|
||||
@@ -58,27 +58,28 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
var equipped = context.GetState<EquippedEntityState>().GetValue();
|
||||
context.GetState<WeaponEntityState>().SetValue(equipped);
|
||||
}
|
||||
|
||||
protected override IReadOnlyCollection<Func<float>> GetConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
protected override Consideration[] Considerations { get; } = {
|
||||
// Check if we have a weapon; easy-out
|
||||
new MeleeWeaponEquippedCon(
|
||||
new BoolCurve()),
|
||||
// Don't attack a dead target
|
||||
new TargetIsDeadCon(
|
||||
new InverseBoolCurve()),
|
||||
// Deprioritise a target in crit
|
||||
new TargetIsCritCon(
|
||||
new QuadraticCurve(-0.8f, 1.0f, 1.0f, 0.0f)),
|
||||
// Somewhat prioritise distance
|
||||
new DistanceCon(
|
||||
new QuadraticCurve(-1.0f, 1.0f, 1.02f, 0.0f)),
|
||||
// Prefer weaker targets
|
||||
new TargetHealthCon(
|
||||
new QuadraticCurve(1.0f, 0.4f, 0.0f, -0.02f)),
|
||||
new MeleeWeaponSpeedCon(
|
||||
new QuadraticCurve(1.0f, 0.5f, 0.0f, 0.0f)),
|
||||
new MeleeWeaponDamageCon(
|
||||
new QuadraticCurve(1.0f, 0.25f, 0.0f, 0.0f)),
|
||||
};
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<MeleeWeaponEquippedCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<TargetIsDeadCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetIsCritCon>()
|
||||
.QuadraticCurve(context, -0.8f, 1.0f, 1.0f, 0.0f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<TargetHealthCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, -0.02f),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.5f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponDamageCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.25f, 0.0f, 0.0f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators.Sequences;
|
||||
using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Containers;
|
||||
using Content.Server.AI.Utility.Considerations.Hands;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.Utility.Curves;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Combat;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
{
|
||||
@@ -33,20 +35,26 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
context.GetState<TargetEntityState>().SetValue(_entity);
|
||||
context.GetState<WeaponEntityState>().SetValue(_entity);
|
||||
}
|
||||
|
||||
protected override IReadOnlyCollection<Func<float>> GetConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
protected override Consideration[] Considerations { get; } = {
|
||||
new TargetAccessibleCon(
|
||||
new BoolCurve()),
|
||||
new FreeHandCon(
|
||||
new BoolCurve()),
|
||||
new HasMeleeWeaponCon(
|
||||
new InverseBoolCurve()),
|
||||
new DistanceCon(
|
||||
new QuadraticCurve(-1.0f, 1.0f, 1.02f, 0.0f)),
|
||||
new MeleeWeaponDamageCon(
|
||||
new QuadraticCurve(1.0f, 0.25f, 0.0f, 0.0f)),
|
||||
new MeleeWeaponSpeedCon(
|
||||
new QuadraticCurve(-1.0f, 0.5f, 1.0f, 0.0f)),
|
||||
};
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<TargetAccessibleCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<FreeHandCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<HasMeleeWeaponCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, 1.0f, 1.0f, 0.02f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponDamageCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.25f, 0.0f, 0.0f),
|
||||
considerationsManager.Get<MeleeWeaponSpeedCon>()
|
||||
.QuadraticCurve(context, -1.0f, 0.5f, 1.0f, 0.0f),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.AI.Operators;
|
||||
using Content.Server.AI.Operators.Combat.Melee;
|
||||
@@ -6,13 +7,13 @@ using Content.Server.AI.Utility.Considerations;
|
||||
using Content.Server.AI.Utility.Considerations.Combat;
|
||||
using Content.Server.AI.Utility.Considerations.Combat.Melee;
|
||||
using Content.Server.AI.Utility.Considerations.Movement;
|
||||
using Content.Server.AI.Utility.Curves;
|
||||
using Content.Server.AI.WorldState;
|
||||
using Content.Server.AI.WorldState.States;
|
||||
using Content.Server.AI.WorldState.States.Combat;
|
||||
using Content.Server.AI.WorldState.States.Movement;
|
||||
using Content.Server.GameObjects.Components.Weapon.Melee;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
{
|
||||
@@ -56,23 +57,25 @@ namespace Content.Server.AI.Utility.Actions.Combat.Melee
|
||||
context.GetState<WeaponEntityState>().SetValue(Owner);
|
||||
}
|
||||
|
||||
protected override Consideration[] Considerations { get; } = {
|
||||
new CanUnarmedCombatCon(
|
||||
new BoolCurve()),
|
||||
// Don't attack a dead target
|
||||
new TargetIsDeadCon(
|
||||
new InverseBoolCurve()),
|
||||
// Deprioritise a target in crit
|
||||
new TargetIsCritCon(
|
||||
new QuadraticCurve(-0.8f, 1.0f, 1.0f, 0.0f)),
|
||||
// Somewhat prioritise distance
|
||||
new DistanceCon(
|
||||
new QuadraticCurve(-1.0f, 1.0f, 1.02f, 0.0f)),
|
||||
// Prefer weaker targets
|
||||
new TargetHealthCon(
|
||||
new QuadraticCurve(1.0f, 0.4f, 0.0f, -0.02f)),
|
||||
// TODO: Consider our Speed and Damage to compare this to using a weapon
|
||||
// Also need to unequip our weapon if we have one (xenos can't hold one so no issue for now)
|
||||
};
|
||||
protected override IReadOnlyCollection<Func<float>> GetConsiderations(Blackboard context)
|
||||
{
|
||||
var considerationsManager = IoCManager.Resolve<ConsiderationsManager>();
|
||||
|
||||
return new[]
|
||||
{
|
||||
considerationsManager.Get<CanUnarmedCombatCon>()
|
||||
.BoolCurve(context),
|
||||
considerationsManager.Get<TargetIsDeadCon>()
|
||||
.InverseBoolCurve(context),
|
||||
considerationsManager.Get<TargetIsCritCon>()
|
||||
.QuadraticCurve(context, -0.8f, 1.0f, 1.0f, 0.0f),
|
||||
considerationsManager.Get<DistanceCon>()
|
||||
.QuadraticCurve(context, -1.0f, 1.0f, 1.02f, 0.0f),
|
||||
considerationsManager.Get<TargetHealthCon>()
|
||||
.QuadraticCurve(context, 1.0f, 0.4f, 0.0f, -0.02f),
|
||||
// TODO: Consider our Speed and Damage to compare this to using a weapon
|
||||
// Also need to unequip our weapon if we have one (xenos can't hold one so no issue for now)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user