예제 #1
0
        public void Eat(int amount)
        {
            if (!_alive || MM.Asleep || _pendingKill)
            {
                return;
            }

            int deltaEnergy = 0;
            int deltaFood   = 0;
            int deltaWater  = 0;

            if (World.Food < amount)
            {
                amount = World.Food;
            }

            if (_food < Init.EatThreshold)
            {
                deltaEnergy -= Init.EnergyDrain;
                deltaFood   += amount;
                deltaWater  -= Init.WaterDrain / 2;
            }
            else
            {
                deltaEnergy -= Init.EnergyDrain / 2;
                deltaFood   += amount / 2;
                deltaWater  -= Init.WaterDrain * 2;
            }

            if (_water <= -deltaWater)
            {
                MM.AffectUrge(Urge.Drink, 1);
                return;
            }

            World.UseFood(deltaFood);
            World.Reclaim(0, -deltaWater);
            MM.Action(Urge.Eat);

            _energy += deltaEnergy;
            _food   += deltaFood;
            _water  += deltaWater;
            ++_eatCount;

            if (_food > Init.Food)
            {
                _hp -= Init.HpDrain * 4;

                MM.AffectUrge(Urge.Eat, -2);
                MM.AffectUrge(Urge.Excrete, 1);
            }

            if (_hp <= 0 && _deathBy == DeathBy.None)
            {
                _deathBy     = DeathBy.Gluttony;
                _pendingKill = true;
            }
        }
예제 #2
0
        private void ProcessBodilyFunctions()
        {
            bool    excreteW = false;
            bool    excreteF = false;
            int     dHp      = 0;
            int     dEnergy  = 0;
            int     dFood    = 0;
            int     dWater   = 0;
            DeathBy causeW   = DeathBy.None;
            DeathBy causeF   = DeathBy.None;

            DeltaWater(ref dHp, ref dEnergy, ref dWater, ref causeW, ref excreteW);
            DeltaFood(ref dHp, ref dEnergy, ref dFood, ref causeF, ref excreteF);

            if (MM.Asleep)
            {
                // don't lose resources while asleep
                dEnergy = 0;
                dFood   = 0;
                dWater  = 0;
            }
            else
            {
                if (excreteW)
                {
                    MM.AffectUrge(Urge.Drink, -1);
                    MM.Action(Urge.Excrete);
                }

                if (excreteF)
                {
                    MM.AffectUrge(Urge.Eat, -1);
                    MM.Action(Urge.Excrete);
                }
            }

            World.Reclaim(-dFood, -dWater);

            _hp     += dHp;
            _energy += dEnergy;
            _food   += dFood;
            _water  += dWater;

            if (_hp < 0 && _deathBy == DeathBy.None)
            {
                _deathBy     = DeltaDeathBy(causeW, causeF);
                _pendingKill = true;
            }
        }
예제 #3
0
        public void Drink(int amount)
        {
            if (!_alive || MM.Asleep || _pendingKill)
            {
                return;
            }

            int deltaEnergy = 0;
            int deltaWater  = 0;

            if (World.Water < amount)
            {
                amount = World.Water;
            }

            if (_water < Init.DrinkThreshold)
            {
                deltaEnergy -= Init.EnergyDrain;
                deltaWater  += amount;
            }
            else
            {
                deltaEnergy -= Init.EnergyDrain / 2;
                deltaWater  += amount / 2;
            }

            World.UseWater(deltaWater);
            MM.Action(Urge.Drink);

            _energy += deltaEnergy;
            _water  += deltaWater;
            ++_drinkCount;

            if (_water > Init.Water)
            {
                _hp -= Init.HpDrain * 4;

                MM.AffectUrge(Urge.Drink, -2);
                MM.AffectUrge(Urge.Excrete, 1);
            }

            if (_hp <= 0 && _deathBy == DeathBy.None)
            {
                _deathBy     = DeathBy.Overdrinking;
                _pendingKill = true;
            }
        }
예제 #4
0
        public Lifeform(World world, Species species)
        {
            Id        = _id++;
            ParentIdA = -1;
            ParentIdB = -1;
            Species   = species;
            Log       = Logging ? new HashSet <string>() : null;
            World     = world;
            MM        = new MoodManager(this);

            Init     = SpeciesContainer.INIT[species];
            _alive   = true;
            _deathBy = DeathBy.None;

            _hp     = Init.Hp;
            _energy = Init.Energy;
            _food   = Init.Food;
            _water  = Init.Water;
        }
예제 #5
0
        private void DeltaFood(ref int hp, ref int energy, ref int food,
                               ref DeathBy cause, ref bool excrete)
        {
            if (_food > Init.Food)
            {
                excrete = true;
                hp     -= Init.HpDrain * 8;
                energy -= Init.EnergyDrain * 8;
                food   -= Init.FoodDrain * 8;
                cause   = DeathBy.Gluttony;
            }
            else if (_food > Init.EatThreshold)
            {
                excrete = true;
                energy -= Init.EnergyDrain * 4;
                food   -= Init.FoodDrain * 4;
            }
            else if (_food > Init.FoodDrain)
            {
                energy -= Init.EnergyDrain;
                food   -= Init.FoodDrain;
            }
            else if (_food > 0)
            {
                hp     -= Init.HpDrain * 4;
                energy -= Init.EnergyDrain * 2;
                food   -= _food;
                cause   = DeathBy.Starvation;
            }
            else
            {
                hp     -= Init.HpDrain * 16;
                energy -= Init.EnergyDrain * 4;

                if (cause == DeathBy.None)
                {
                    cause = DeathBy.Starvation;
                }
            }
        }
예제 #6
0
        private void DeltaWater(ref int hp, ref int energy, ref int water,
                                ref DeathBy cause, ref bool excrete)
        {
            if (_water > Init.Water)
            {
                excrete = true;
                hp     -= Init.HpDrain * 8;
                energy -= Init.EnergyDrain * 8;
                water  -= Init.WaterDrain * 8;
                cause   = DeathBy.Overdrinking;
            }
            else if (_water > Init.DrinkThreshold)
            {
                excrete = true;
                energy -= Init.EnergyDrain * 4;
                water  -= Init.WaterDrain * 4;
            }
            else if (_water > Init.WaterDrain)
            {
                energy -= Init.EnergyDrain;
                water  -= Init.WaterDrain;
            }
            else if (_water > 0)
            {
                hp     -= Init.HpDrain * 4;
                energy -= Init.EnergyDrain * 2;
                water  -= _water;
                cause   = DeathBy.Dehydration;
            }
            else
            {
                hp     -= Init.HpDrain * 16;
                energy -= Init.EnergyDrain * 4;

                if (cause == DeathBy.None)
                {
                    cause = DeathBy.Dehydration;
                }
            }
        }
예제 #7
0
        private static DeathBy DeltaDeathBy(DeathBy causeW, DeathBy causeF)
        {
            DeathBy cause;

            if (causeW == DeathBy.None)
            {
                cause = causeF;
            }
            else
            {
                if (causeF == DeathBy.None)
                {
                    cause = causeW;
                }
                else
                {
                    cause = DeathBy.Malnutrition;
                }
            }

            return(cause);
        }
예제 #8
0
        private void ProcessSleep()
        {
            if (_pendingKill)
            {
                return;
            }

            if (MM.Asleep)
            {
                _hp     -= Init.HpDrain;
                _energy += Init.EnergyDrain * 8;
                ++_sleepCount;

                if (_energy >= Init.Energy || _hp < Init.HpDrain * 32)
                {
                    MM.Asleep = false;
                }

                return;
            }

            if (_energy < Init.SleepThreshold)
            {
                MM.Asleep = true;
                MM.Action(Urge.Sleep);

                if (_energy <= 0)
                {
                    _hp -= Init.HpDrain * 10;

                    if (_hp < 0 && _deathBy == DeathBy.None)
                    {
                        _deathBy     = DeathBy.Exhaustion;
                        _pendingKill = true;
                    }
                }
            }
        }
예제 #9
0
        private void Kill()
        {
            _pendingKill = false;
            _alive       = false;

            if (_deathBy == DeathBy.None)
            {
                if (_energy <= 0)
                {
                    _deathBy = DeathBy.Exhaustion;
                }
                else if (_food <= 0)
                {
                    _deathBy = DeathBy.Starvation;
                }
                else if (_water <= 0)
                {
                    _deathBy = DeathBy.Dehydration;
                }
            }

            _hp = -1;
            World.Decompose(_food, _water);
        }