예제 #1
0
 IEnumerator EatPlant(FoliageFoodSource plant)
 {
     while (!Physics.OverlapSphere(transform.position, 1f).Contains(plant.GetComponent <Collider>()))
     {
         navAgent.SetDestination(plant.transform.position);
         yield return(new WaitForSeconds(1f));
     }
     while (Nutrition < maxNutrition && plant.remainingNutrition != 0)
     {
         if (plant.remainingNutrition < 0.01f)
         {
             Nutrition += plant.remainingNutrition;
             plant.remainingNutrition = 0;
         }
         else
         {
             Nutrition += 0.01f;
             plant.remainingNutrition -= 0.01f;
             yield return(null);
         }
     }
     plant.Release();
     activity = CreatureActivity.Idle;
     yield break;
 }
예제 #2
0
 public void Eat()
 {
     if (dietType == DietType.Carnivore)
     {
         CreatureDebug("EF: " + Sight.EdibleFood.Length + ", CFN: " + (Sight.ClosestFood == null));
     }
     if ((Sight.EdibleFood.Length == 0 || Sight.ClosestFood == null) &&
         (dietType == DietType.Carnivore ? (PreviousFood.Count == 0 || CreatureSight.Closest <GameObject>(this, PreviousFood.Keys.Select(f => f.gameObject).ToArray()) == null) : true))
     {
         if (dietType == DietType.Carnivore)
         {
             CreatureDebug("can't find food (" + PreviousFood.Count + ")");
         }
         Roam(4, 8);
     }
     else
     {
         if (dietType == DietType.Carnivore)
         {
             CreatureDebug("finding food");
         }
         activity = CreatureActivity.Eating;
         if (dietType == DietType.Carnivore && PreviousFood.Count > 0)
         {
             if (dietType == DietType.Carnivore)
             {
                 CreatureDebug("looking for past food (" + PreviousFood.Count + ")");
             }
             FoodSource closestMeat = CreatureSight.Closest <FoodSource>(this, PreviousFood.Keys.Select(f => f.gameObject).ToArray());
             navAgent.SetDestination(closestMeat.transform.position);
             closestMeat.Reserve();
             StartCoroutine(EatMeat((MeatFoodSource)closestMeat));
         }
         else
         {
             if (dietType == DietType.Carnivore)
             {
                 CreatureDebug("looking for food");
             }
             navAgent.SetDestination(Sight.ClosestFood.transform.position);
             Sight.ClosestFood.Reserve();
             if (Sight.ClosestFood == null)
             {
                 return;                            // in the hypothetical situation that the plant dies before the creature is able to move.
             }
             if (Sight.ClosestFood.type == FoodType.Foliage)
             {
                 StartCoroutine(EatPlant((FoliageFoodSource)Sight.ClosestFood));
             }
             else if (Sight.ClosestFood.type == FoodType.Meat)
             {
                 StartCoroutine(EatMeat((MeatFoodSource)Sight.ClosestFood));
             }
         }
     }
 }
예제 #3
0
    private void Start()
    {
        DataCollector.main.BirthWrite(this);
        Nutrition = maxNutrition;
        Hydration = maxHydration;

        attractabilityThreshold = Mathf.Lerp(0.1f, 0.8f, genes[Genotype.Attractability]);
        activity = CreatureActivity.Idle;

        StartCoroutine(Live());
        StartCoroutine(Idle());
    }
예제 #4
0
 public void StartMate(Creature partnerCreature)
 {
     if (partnerCreature == null)
     {
         return;
     }
     partner = partnerCreature;
     partnerCreature.partner = this;
     activity           = CreatureActivity.Mating;
     partner.activity   = CreatureActivity.Mating;
     navAgent.isStopped = true;;
     StartCoroutine(Mate());
 }
예제 #5
0
 public void Hydrate()
 {
     if (Sight.Water.Length == 0)
     {
         Roam(4, 8);
     }
     else
     {
         activity = CreatureActivity.Drinking;
         navAgent.SetDestination(Sight.ClosestWater.transform.position);
         StartCoroutine(Drink(Sight.ClosestWater));
     }
 }
예제 #6
0
 IEnumerator FollowCreature(Creature parent)
 {
     if (mother == null)
     {
         yield break;
     }
     while (!Physics.OverlapSphere(transform.position, 3f).Contains(mother.GetComponent <Collider>()))
     {
         navAgent.SetDestination(mother.transform.position);
         yield return(new WaitForSeconds(0.1f));
     }
     activity = CreatureActivity.Idle;
     yield break;
 }
예제 #7
0
 IEnumerator Drink(WaterBlock water)
 {
     while (!Physics.OverlapSphere(transform.position, 1f).Contains(water.GetComponent <Collider>()))
     {
         navAgent.SetDestination(water.transform.position);
         yield return(new WaitForSeconds(1f));
     }
     while (Hydration < maxHydration)
     {
         Hydration += 0.03f;
         yield return(null);
     }
     activity = CreatureActivity.Idle;
     yield break;
 }
예제 #8
0
    public IEnumerator Mate()
    {
        for (;;)
        {
            if (partner == null)
            {
                yield break;
            }
            if (Physics.OverlapSphere(transform.position, 1.5f).Contains(partner.GetComponent <Collider>()))
            {
                if (matingTimer.IsRunning == false)
                {
                    matingTimer.Reset();
                    matingTimer.Start();
                }
                else if (matingTimer.ElapsedMilliseconds > 3 * 1000)
                {
                    activity         = CreatureActivity.Idle;
                    partner.activity = CreatureActivity.Idle;

                    if (partner.gender == GenderType.Female)
                    {
                        partner.gestation.Reproduce(this);
                        partner.children += partner.gestation.childCount;
                        children         += partner.gestation.childCount;
                    }

                    matingTimer.Reset();
                    matingTimer.Stop();

                    partner.ReproductiveUrge    = 0f;
                    partner.lastReproductionTry = Time.time;
                    partner.lastReproduction    = Time.time;

                    ReproductiveUrge    = 0f;
                    lastReproductionTry = Time.time;
                    lastReproduction    = Time.time;
                    yield break;
                }
            }
            else
            {
                matingTimer.Stop();
                matingTimer.Reset();
            }
            yield return(null);
        }
    }
예제 #9
0
    IEnumerator Idle()
    {
        for (; ;)
        {
            if (transform.up.y < 0.99)
            {
                activity = CreatureActivity.Rotating;
                Quaternion q = Quaternion.FromToRotation(transform.up, Vector3.up) * transform.rotation;
                transform.rotation = Quaternion.Slerp(transform.rotation, q, quickSpeed * Mathf.Lerp(1f, 6f, ability[Genotype.Speed]));
                yield return(null);
            }
            else if (activity == CreatureActivity.Rotating)
            {
                activity = CreatureActivity.Idle;
            }

            if (partner != null && activity == CreatureActivity.Mating)
            {
                navAgent.SetDestination(partner.transform.position);
            }

            if (activity == CreatureActivity.Idle)
            {
                if (Hydration < maxHydration / 2)
                {
                    Hydrate();
                }
                else if (Nutrition < maxNutrition / 2)
                {
                    Eat();
                }
                else if (childGrowth <= 0.9f && mother != null && !Physics.OverlapSphere(transform.position, 4f).Contains(mother.GetComponent <Collider>()))
                {
                    activity = CreatureActivity.Navigating;
                    StartCoroutine(FollowCreature(mother));
                }
                else if (ReproductiveUrge > 0.6 && Time.time > lastReproductionTry + Mathf.Lerp(45f, 1f, ReproductiveUrge) && childGrowth >= 1)
                {
                    FindMate();
                }
                else if (Time.time > lastRoam + Random.Range(1f, 1.3f))
                {
                    Roam(2, Mathf.FloorToInt(Mathf.Lerp(4, 12, ability[Genotype.Sight])));
                }
            }
            yield return(null);
        }
    }
예제 #10
0
    public void Roam(int minDistance, int maxDistance)
    {
        Vector3 roamVector;

        do
        {
            bool negativeX = (Random.Range(0, 2) == 1);
            bool negativeZ = (Random.Range(0, 2) == 1);

            float x = Random.Range(minDistance, maxDistance);
            float z = Random.Range(minDistance, maxDistance);

            roamVector = transform.position + new Vector3(
                negativeX ? -x : x,
                0,
                negativeZ ? -z : z
                );
        } while (Physics.OverlapCapsule(roamVector, roamVector - new Vector3(0, -1, 0), 0.1f).Where(collider => collider.GetComponent <WaterBlock>() != null).Count() > 0);

        activity = CreatureActivity.Roaming;
        navAgent.SetDestination(roamVector);
    }
예제 #11
0
    private void Update()
    {
        if (Health < 0 && Nutrition == 0)
        {
            Die(DeathCause.Nutrition);
        }
        else if (Health < 0 && Hydration == 0)
        {
            Die(DeathCause.Hydration);
        }
        else if (Health < 0)
        {
            Die(DeathCause.Injury);
        }

        float remainingDistance = navAgent.remainingDistance;

        if ((remainingDistance != Mathf.Infinity && navAgent.pathStatus == NavMeshPathStatus.PathComplete && navAgent.remainingDistance == 0) && activity == CreatureActivity.Roaming)
        {
            lastRoam = Time.time;
            activity = CreatureActivity.Idle;
        }
    }
예제 #12
0
 IEnumerator EatMeat(MeatFoodSource meat)
 {
     if (dietType == DietType.Carnivore)
     {
         CreatureDebug("starting meat");
     }
     if (meat == null)
     {
         yield break;
     }
     chaseCoroutine = StartCoroutine(GoToObject(meat.gameObject));
     chaseTimer.Reset();
     chaseTimer.Start();
     while (!Physics.OverlapSphere(transform.position, 1.5f).Contains(meat.GetComponent <Collider>()))
     {
         if (chaseTimer.ElapsedMilliseconds > 15000f)
         {
             chaseTimer.Stop();
             chaseTimer.Reset();
             yield break;
         }
         yield return(new WaitForSeconds(0.1f));
     }
     if (meat.GetComponent <Creature>() != null)
     {
         Creature meatCreature = meat.GetComponent <Creature>();
         if (dietType == DietType.Carnivore)
         {
             CreatureDebug("attacking " + meatCreature.ID + " (" + meatCreature.Health + ")");
         }
         while (meatCreature.Health > Mathf.Lerp(0.2f, 2f, ability[Genotype.Strength]) * Mathf.Lerp(1.5f, 0.5f, meatCreature.ability[Genotype.Resistance]))
         {
             meatCreature.Health -= Mathf.Lerp(0.2f, 2f, ability[Genotype.Strength]) * Mathf.Lerp(1.5f, 0.5f, meatCreature.ability[Genotype.Resistance]);
             yield return(new WaitForSeconds(Mathf.Lerp(1.2f, 0.1f, ability[Genotype.Speed])));
         }
         meat.GetComponent <Creature>().Die(DeathCause.Injury);
         if (dietType == DietType.Carnivore)
         {
             CreatureDebug("killed. meat time.");
         }
     }
     while (Nutrition < maxNutrition && meat.remainingNutrition != 0)
     {
         if (meat.remainingNutrition < 0.05f)
         {
             Nutrition += meat.remainingNutrition;
             meat.remainingNutrition = 0;
         }
         else
         {
             Nutrition += 0.05f;
             meat.remainingNutrition -= 0.05f;
             yield return(null);
         }
     }
     if (meat != null && meat.remainingNutrition != 0)
     {
         PreviousFood.Add(meat, Time.time);
     }
     activity = CreatureActivity.Idle;
     yield break;
 }