Exemplo n.º 1
0
    private bool ShouldTargetHuman <T>(Human otherHuman) where T : IResource
    {
        if (otherHuman.Dead)
        {
            return(false);
        }

        var isFoodSource = typeof(T) == typeof(IFoodSource);
        var aggression   = Aggression.Get(_team, otherHuman._team);

        if (aggression == Aggression.Level.Neutral)
        {
            // Only if I'm starving
            return(isFoodSource && Hunger <= 5);
        }

        if (aggression == Aggression.Level.Aggressive)
        {
            // Only if I'm hungry
            return(isFoodSource && Hunger <= MAX_HUNGER / 2);
        }

        // If we're friendly we'll share, if we're murderous we'll kill
        return(true);
    }
Exemplo n.º 2
0
 public void TakeFood(Human taker)
 {
     if (Aggression.Get(_team, taker._team) == Aggression.Level.Friendly)
     {
         // Sharing is caring
         if (HasFood)
         {
             Food--;
             taker.Feed(1);
         }
     }
     else
     {
         // I have been killed
         Dead = true;
         SetAnimationState(AnimationState.Dying);
         taker.Feed(Food);
         Food = 0;
         // I shall be avenged
         Aggression.Adjust(_team, taker._team, 15);
     }
 }
Exemplo n.º 3
0
    public override void _Process(float delta)
    {
        if (Dead)
        {
            return;
        }

        Thirst -= delta;
        Hunger -= delta;

        if (Thirst < MAX_THIRST / 2)
        {
            var waterSource = _targetResource as IWaterSource;
            if (waterSource == null || !waterSource.HasWater)
            {
                // Seek water
                var waterSources = new List <IWaterSource>();
                Group.CallGroup(GetTree(), Group.WaterSources, source =>
                {
                    if (source.HasWater)
                    {
                        waterSources.Add(source);
                    }
                });
                TargetClosestResource(waterSources);
                waterSource = _targetResource as IWaterSource;
            }

            if (waterSource != null && waterSource.HasWater && Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED)
            {
                waterSource.TakeWater(this);
                _targetResource = null;
            }
        }
        else if (Hunger < MAX_HUNGER / 2)
        {
            if (Food > 0)
            {
                // If we have food, eat
                Eat();
            }
            else
            {
                // Otherwise, seek food
                var foodSource = _targetResource as IFoodSource;
                if (foodSource == null || !foodSource.HasFood)
                {
                    var foodSources = new List <IFoodSource>();
                    Group.CallGroup(GetTree(), Group.FoodSources, source =>
                    {
                        if (!source.HasFood)
                        {
                            return;
                        }

                        var humanSource = source as Human;
                        if (humanSource != null)
                        {
                            if (!ShouldTargetHuman <IFoodSource>(humanSource))
                            {
                                return;
                            }
                        }

                        foodSources.Add(source);
                    });
                    TargetClosestResource(foodSources);
                    foodSource = _targetResource as IFoodSource;
                }

                if (foodSource != null && foodSource.HasFood && Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED)
                {
                    foodSource.TakeFood(this);
                    _targetResource = null;
                }
            }
        }
        else
        {
            // Not thirsty and not hungry. Anyone we wanna murder nearby?
            var murderTarget = _targetResource as Human;
            if (murderTarget == null || murderTarget.Dead)
            {
                var peopleIWantToKill = new List <Human>();
                Group.Humans.Call(GetTree(), human =>
                {
                    if (human.Dead || Position.DistanceSquaredTo(human.Position) > RAGE_RADIUS_SQUARED)
                    {
                        return;
                    }

                    var aggression = Aggression.Get(_team, human._team);
                    if (aggression == Aggression.Level.Murderous)
                    {
                        peopleIWantToKill.Add(human);
                    }
                });
                TargetClosestResource(peopleIWantToKill);
            }

            murderTarget = _targetResource as Human;
            if (murderTarget != null && !murderTarget.Dead && Position.DistanceSquaredTo(murderTarget.Position) <= RAGE_RADIUS_SQUARED)
            {
                // Humans can move, so update the target position regularly
                _targetPosition = murderTarget.Position;
                if (Position.DistanceSquaredTo(_targetPosition) <= INTERACTION_RADIUS_SQUARED)
                {
                    // This will kill them and take all their stuff. Nice!
                    murderTarget.TakeFood(this);
                    _targetResource = null;
                }
            }
        }

        if (_targetResource != null)
        {
            SetAnimationState(AnimationState.Walking);
            var velocity = (_targetPosition - Position).Normalized() * SPEED * delta;
            Position += velocity;
        }
        else
        {
            SetAnimationState(AnimationState.Standing);
        }

        if (Thirst <= 0 || Hunger <= 0)
        {
            Dead = true;
            SetAnimationState(AnimationState.Dying);
        }
    }