Entitas
Entitas copied to clipboard
Using Services more often
Hi,
In my project I'm using Services for more than just external communication. At the moment I've got a TargetingService and a SightService which both derive from ITargetingService and ISightService respectively. This is so I can expose common methods like GetSightTargets instead of querying an entity for the component SightTargetsComponent. By doing this I do not have to worry about what component is where or what component to add to perform something.
Is this the right way to do it?
using System.Collections.Generic;
using Entitas;
public class SiegeTargetService : ITargetService, IDestroyedListener
{
private Contexts _contexts;
private IGroup<GameEntity> _targets;
private ISightService _sightService;
public SiegeTargetService(Contexts contexts)
{
_contexts = contexts;
_targets = _contexts.game.GetGroup(GameMatcher.AllOf(GameMatcher.Position, GameMatcher.Asset));
_sightService = SiegeServices.SightService;
}
public IEntity GetTarget(IEntity targeter)
{
var e = (GameEntity)targeter;
if (e.hasTarget == false)
{
return null;
}
else
{
return _contexts.game.GetEntityWithId(e.target.value);
}
}
public bool HasTarget(IEntity targeter)
{
var e = (GameEntity)targeter;
VerifyTarget(targeter);
if (e.hasTarget == false)
{
return false;
}
return true;
}
public void OnDestroyed(GameEntity entity)
{
var targeters = _contexts.game.GetEntitiesWithTarget(entity.id.value);
foreach (GameEntity targeter in targeters)
{
targeter.RemoveTarget();
}
}
public void UpdateTarget(IEntity targeter)
{
var e = (GameEntity)targeter;
var sightTargets = _sightService.GetSightTargets(targeter);
GameEntity newTarget = null;
//TODO : IF CANNON TARGET LIKE THIS
//TODO : IF MUSKETEER TARGET LIKE THIS
if (sightTargets.Count > 0)
{
newTarget = _contexts.game.GetEntityWithId(sightTargets[0]);
}
if (newTarget == null)
{
if (e.hasTarget)
{
e.RemoveTarget();
}
}
else
{
if (e.hasTarget)
{
e.ReplaceTarget(newTarget.id.value);
}
else
{
e.AddTarget(newTarget.id.value);
}
}
}
public void VerifyTarget(IEntity entity)
{
var e = (GameEntity)entity;
if (e.hasTarget == false)
{
return;
}
var target = _contexts.game.GetEntityWithId(e.target.value);
if (_sightService.CanSee(e, target) == false)
{
e.RemoveTarget();
return;
}
}
}
using System.Collections.Generic;
using Entitas;
public class SiegeSightService : ISightService
{
private Contexts _contexts;
private IGroup<GameEntity> _targets;
public SiegeSightService(Contexts contexts)
{
_contexts = contexts;
_targets = _contexts.game.GetGroup(GameMatcher.AllOf(GameMatcher.Position, GameMatcher.Asset));
}
public bool CanSee(IEntity entity, IEntity target)
{
var e = (GameEntity)entity;
var t = (GameEntity)target;
if (e.hasSightTargets == false)
{
return false;
}
return (e.sightTargets.targets.IndexOf(t.id.value) > -1);
}
public List<int> GetSightTargets(IEntity entity)
{
var e = (GameEntity)entity;
if (e.hasSightTargets)
{
return e.sightTargets.targets;
}
return new List<int>();
}
public void UpdateSight(IEntity targeter)
{
var t = (GameEntity)targeter;
var inSight = new List<int>();
foreach (GameEntity target in _targets.GetEntities())
{
if (target.id.value == t.id.value)
{
continue;
}
var distance = (target.position.value - t.position.value).magnitude;
if (distance <= t.sight.distance)
{
inSight.Add(target.id.value);
}
}
if (inSight.Count > 0)
{
if (t.hasSightTargets)
{
t.ReplaceSightTargets(inSight);
}
else
{
t.AddSightTargets(inSight);
}
}
else
{
if (t.hasSightTargets)
{
t.RemoveSightTargets();
}
}
}
}
Cheers