public GravitationalFieldPrimitive(Game1 game, GravitationalFieldPrimitiveSettings settings)
: base(game, settings = settings == null ? new GravitationalFieldPrimitiveSettings() : settings)
{
// Higher multiplier = Higher gravity (stronger attractive force)
// Maximum value for 'MaxAcceleration' should be 50
// Object shaking occurs after the max value unless the 'space.TimeStepSettings.TimeStepDuration' value is decreased
gravField = new GravitationalField(
new InfiniteForceFieldShape(),
settings.Position,
settings.GravitationalFieldStrength,
50
);
// Force entities in range to wake up
gravField.ForceWakeUp = true;
game.Space.Add(gravField);
}
How can I get the GravitationalField class to ignore the dynamic entity associated with it in the GravitationalFieldPrimitive class?
This is not normally a problem if the associated entity is kinematic but it needs to be ignored when the associated entity is dynamic.
/// <summary>
/// Defines the area in which a force field works using an entity's shape.
/// </summary>
public class InfiniteForceFieldShape : ForceFieldShape
{
/// <summary>
/// Determines the possibly involved entities.
/// </summary>
/// <returns>Possibly involved entities.</returns>
public override IList<Entity> GetPossiblyAffectedEntities()
{
return (ForceField as ISpaceObject).Space.Entities;
}
/// <summary>
/// Determines if the entity is affected by the force field.
/// </summary>
/// <param name="testEntity">Entity to test.</param>
/// <returns>Whether the entity is affected.</returns>
public override bool IsEntityAffected(Entity testEntity)
{
return true;
}
}
GetPossiblyAffectedEntities runs first to gather candidates. Since it's called from a single threaded context, keeping this fast can be important. The following IsEntityEffected allows fine grained checks to run on each candidate from a multithreaded context. So, you could override the IsEntityAffected method and check the testEntity against the followed entity.
public override bool IsEntityAffected(Entity testEntity)
{
var o = testEntity.CollisionInformation.Tag as GravitationalFieldPrimitive;
return o == null ? true : false;
}
That would work; the cost of that method will likely be completely overwhelmed by everything else going on. If testing shows you need every nanosecond, changing it to a single direct entity equality test would probably be marginally faster (by avoiding a cast), but it almost certainly won't matter.
public class InfiniteForceFieldShapeCustom : ForceFieldShape
{
public Entity owner;
public InfiniteForceFieldShapeCustom(Entity owner)
{
this.owner = owner;
}
/// <summary>
/// Determines the possibly involved entities.
/// </summary>
/// <returns>Possibly involved entities.</returns>
public override IList<Entity> GetPossiblyAffectedEntities()
{
return (ForceField as ISpaceObject).Space.Entities;
}
/// <summary>
/// Determines if the entity is affected by the force field.
/// </summary>
/// <param name="testEntity">Entity to test.</param>
/// <returns>Whether the entity is affected.</returns>
public override bool IsEntityAffected(Entity testEntity)
{
//var o = testEntity.CollisionInformation.Tag as GravitationalFieldPrimitive;
//return o == null ? true : false;
return testEntity != owner;
}
}