Entitas icon indicating copy to clipboard operation
Entitas copied to clipboard

Using Services more often

Open svanderweele opened this issue 6 years ago • 0 comments

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

svanderweele avatar Mar 09 '18 09:03 svanderweele