Example #1
0
        public Campfire(int x, int y) : base(x, y, 10)
        {
            Size       = 25;
            RenderMode = RenderContextMode.ObjectFirst;
            image      = Utilities.GetResourceImage("campfirelit.png");
            RenderContext.AddAccessory(new Halo(13, 13, 200));

            FleeFromThisUtility = new ActionUtility(new FleeAction(this), new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, 0.0025)
            });
        }
Example #2
0
        public override List <ActionUtility> GetAdvertisedActions(Entity entity, double mod)
        {
            List <ActionUtility> actionAds = new List <ActionUtility>();

            if (entity is Person)
            {
                actionAds.Add(new ActionUtility(new GuardBaseAction(Position, 800), new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.guardBaseDelta)
                }));
            }

            return(actionAds);
        }
Example #3
0
        public override List <ActionUtility> GetAdvertisedActions(Entity entity, double mod)
        {
            List <ActionUtility> actionUtilities = new List <ActionUtility>();

            if (entity is Person person)
            {
                // males attack or run away from all animal types. females run away or ignore based on animal types.
                // entity can defeat this animal in combat or the animal can't fight back.
                if (person.Sex == Sex.Male)
                {
                    if (this.Health / entity.Strength > person.GetHealth() / this.Strength || Type == AnimalType.Hog || Type == AnimalType.Goat)
                    {
                        actionUtilities.Add(AttackThisUtility);
                    }
                    else // Male runs away from scary animal.
                    {
                        actionUtilities.Add(FleeFromThisUtility);
                    }
                }
                else
                {
                    if (Type == AnimalType.Bear || Type == AnimalType.Wolf)
                    {
                        // Weak males and females should run away from the animal.
                        actionUtilities.Add(FleeFromThisUtility);
                    }
                }
            }
            else if (entity is Animal animal)
            {
                if (this.Type == AnimalType.Goat && animal.Type == AnimalType.Wolf) // Wolves will attack goats.
                {
                    actionUtilities.Add(AttackThisUtility);
                }
                else if (this.Type == AnimalType.Wolf && animal.Type == AnimalType.Goat) // Goats will run from wolves.
                {
                    actionUtilities.Add(FleeFromThisUtility);
                }
                else if (this.Type != AnimalType.Bear && this.Type == animal.Type) // All but bears will travel in packs.
                {
                    actionUtilities.Add(new ActionUtility(new FollowAction(this, FollowDistance), new Tuple <Need, double>[]
                    {
                        ActionUtility.NewPair(Need.JobFullfilment, 0.002)
                    }));
                }
            }

            return(actionUtilities);
        }
Example #4
0
        public override List <ActionUtility> GetAdvertisedActions(Entity entity, double mod)
        {
            List <ActionUtility> actionUtilities = new List <ActionUtility>();

            if (entity is Person person)
            {
                if (appleCount > 0)
                {
                    actionUtilities.Add(new ActionUtility(new HarvestAction(this), new Tuple <Need, double>[]
                    {
                        ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.harvestPlantDelta)
                    }));
                }
            }

            return(actionUtilities);
        }
Example #5
0
        public void DecideAction(Animal animal, List <GameObject> nearbyObjects)
        {
            List <ActionUtility> actionAds = nearbyObjects.
                                             Where(o => o != animal)
                                             .SelectMany(o => o.GetAdvertisedActions(animal, 0.0)).ToList();

            actionAds.Add(new ActionUtility(animal.IdleAction, new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, 0.002)
            }));

            EntityAction attackerResponseAction;

            // Add actions to respond to the attacker being nearby.
            // Bears will always attack nearby entities, but wolves might not, and goats and hogs will not.
            if (animal.Attacker != null && nearbyObjects.Contains(animal.Attacker))
            {
                if (animal.Type == AnimalType.Bear)
                {
                    attackerResponseAction = new AttackAction(animal.Attacker);
                }
                // Wolves will fight back if it can win. I.e. it will take less ticks for the wolf to kill the attacker than for the
                //  attacker to kill the wolf.
                else if (animal.Type == AnimalType.Wolf && animal.GetHealth() / animal.Attacker.Strength > animal.GetHealth() / animal.Strength)
                {
                    attackerResponseAction = new AttackAction(animal.Attacker);
                }
                else
                {
                    attackerResponseAction = new FleeAction(animal.Attacker);
                }
                actionAds.Add(new ActionUtility(attackerResponseAction, new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.attackerResponseDelta)
                }));
            }

            EntityAction bestAction = utilityDecider.GetBestAction(animal, actionAds);

            if (!Utilities.AreSameBaseType(animal.Action, bestAction))
            {
                animal.TrySetAction(bestAction);
            }
        }
Example #6
0
        private Animal(int x, int y, AnimalType type) : base(1.5, 10, x, y, GetBaseColor(type), 5)
        {
            Type = type;
            // Set all needs in the middle. These won't be updated right now, but they will be used for Animal decision making.
            Hunger         = 0.5;
            Social         = 0.5;
            Lust           = 0.5;
            Tiredness      = 0.5;
            Boredom        = 0.5;
            JobFullfilment = 0.5;

            AttackThisUtility = new ActionUtility(AttackThisAction, new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, 0.04)
            });
            FleeFromThisUtility = new ActionUtility(new FleeAction(this), new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, 0.0025)
            });
        }
Example #7
0
        public PersonBrain(int personLimit, int desiredFoodCount, OrderedPair <int> housePosition, RectangleF houseBox)
        {
            this.personLimit      = personLimit;
            this.desiredFoodCount = desiredFoodCount;
            this.housePosition    = housePosition;
            houseRectangle        = houseBox;
            Tasks = new List <Task>();

            utilityDecider = new UtilityDecider <Need>();

            utilityDecider.AddResponseFunction(Need.Hunger, x => x);
            utilityDecider.AddResponseFunction(Need.Social, x => x);
            utilityDecider.AddResponseFunction(Need.Lust, x => x);
            utilityDecider.AddResponseFunction(Need.Tiredness, x => x);
            utilityDecider.AddResponseFunction(Need.Boredom, x => x);
            utilityDecider.AddResponseFunction(Need.JobFullfilment, x => x);

            dropUtility = new ActionUtility(new DropAction(houseRectangle), new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.dropFoodDelta)
            });
        }
Example #8
0
        // Uses the person's needs and the list of GameObjects that are nearby
        public void DecideAction(Person person, List <GameObject> nearbyObjects, int personCount, int food, int mouseX, int mouseY)
        {
            //person.SetAction(new FollowMouseAction(mouseX, mouseY, housePosition, houseRectangle));

            double personCountMod = (personCount == 0 ? 1.0 : food / (2 * personCount));

            List <ActionUtility> actionAds = nearbyObjects
                                             .Where(o => o != person)
                                             // Kinda clunky but this will allow extra data to control action advertisements.
                                             .SelectMany(o => o is Person ? o.GetAdvertisedActions(person, personCountMod) : o.GetAdvertisedActions(person, 0.0))
                                             .ToList();

            //if (personCount >= personLimit)
            //    actionAds = actionAds.Where(ad => !(ad.Action is MateAction)).ToList();


            // Limit the number of people that can be present at one time. This would be more efficient as a check inside Person to prevent
            //  people from advertising a mate action if their are too many people.
            if (personCount >= personLimit)
            {
                actionAds = actionAds.Where(au => !(au.Action is MateAction)).ToList();
            }

            double deliverFoodDelta = person.GetItemCount(ItemType.Apple) / 2;

            // Return food to house.
            actionAds.Add(new ActionUtility(new DeliverFoodAction(houseRectangle), new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, deliverFoodDelta)
            }));
            // Wander around.
            actionAds.Add(new ActionUtility(person.IdleAction, new Tuple <Need, double>[]
            {
                ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.idleActionAdvertisement)
            }));

            // Hunger need.
            if ((person.GetItemCount(ItemType.Apple) > 0 || food > 0) && person.Hunger <= 0.5)
            {
                actionAds.Add(new ActionUtility(new EatAction(), new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.Hunger, 1.0 - person.Hunger)
                }));
            }

            // Tiredness need.
            if ((person.Tiredness < 0.6 || person.Health < 50) && !person.AttackerInRange()) // Sleep required. ** Add check to see if attacker is nearby **.
            {
                actionAds.Add(new ActionUtility(new SleepAction(Person.sleepSeconds, true), new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.Tiredness, DDeltaConfig.sleepActionAdvertisement),
                    ActionUtility.NewPair(Need.Health, DDeltaConfig.sleepHealthAdvertisement)
                }));
            }
            else // Napping optional. This should be picked more often unless there are a lot of other actions to pick.
            {
                actionAds.Add(new ActionUtility(new SleepAction(Person.napSeconds, false), new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.Tiredness, DDeltaConfig.napActionDelta)
                }));
            }

            if (person.GetRectangleF().IntersectsWith(houseRectangle))
            {
                actionAds.Add(dropUtility);
            }

            EntityAction attackerResponseAction;

            if (person.Attacker != null && nearbyObjects.Contains(person.Attacker))
            {
                if (person.Sex == Sex.Male && person.GetHealth() / person.Attacker.Strength > person.GetHealth() / person.Strength)
                {
                    attackerResponseAction = new AttackAction(person.Attacker);
                }
                else
                {
                    attackerResponseAction = new FleeAction(person.Attacker);
                }

                actionAds.Add(new ActionUtility(attackerResponseAction, new Tuple <Need, double>[]
                {
                    ActionUtility.NewPair(Need.JobFullfilment, DDeltaConfig.attackerResponseDelta)
                }));
            }

            // *** Apply action ad filters here from EntitController's tasks ***
            ApplyTaskFilters(actionAds);

            // NOTE: Doesn't filter actions that give 0.0 delta or a negative!
            EntityAction bestAction = utilityDecider.GetBestAction(person, actionAds);

            if (!Utilities.AreSameBaseType(person.Action, bestAction))
            {
                if (!(bestAction is WanderAction)) // Remove leftover velocity from a WanderAction.
                {
                    person.Stop();
                }
                person.TrySetAction(bestAction);
            }
        }