/// <internal/>
 public MoveCompletedEventArgs(int actionID, Action action, ReasonForStop reason,
                               OrganismState blockingOrganism)
     : base(actionID, action)
 {
     Reason = reason;
     BlockingOrganism = blockingOrganism;
 }
Esempio n. 2
0
        /// <summary>
        ///  Derived classes must override (and call Base.CopyStateInto)
        ///  if they have additional state
        /// </summary>
        /// <param name="newInstance">The new state that will hold this state's members</param>
        /// <internal/>
        protected virtual void CopyStateInto(OrganismState newInstance)
        {
            // OrganismID and species are copied via the constructor
            newInstance.Radius = Radius;

            // Safe because they are immutable
            newInstance._currentMoveToAction    = _currentMoveToAction;
            newInstance._currentReproduceAction = _currentReproduceAction;

            // Points aren't immutable, so return a copy
            newInstance._currentPosition = new Point(_currentPosition.X, _currentPosition.Y);

            newInstance._energy           = _energy;
            newInstance.currentFoodChunks = currentFoodChunks;
            newInstance.IncubationTicks   = IncubationTicks;
            newInstance.TickAge           = TickAge;
            newInstance.ReproductionWait  = ReproductionWait;
            newInstance.GrowthWait        = GrowthWait;
            newInstance.DeathReason       = DeathReason;
            newInstance.ActualDirection   = ActualDirection;

            // This object remains mutable because it is information
            // that the renderer updates after the WorldVector has been
            // created.  Nothing besides the renderer should ever touch this
            newInstance.RenderInfo = RenderInfo;
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="newInstance"></param>
        protected override void CopyStateInto(OrganismState newInstance)
        {
            base.CopyStateInto(newInstance);

            ((AnimalState)newInstance).damage   = damage;
            ((AnimalState)newInstance).RotTicks = RotTicks;
            ((AnimalState)newInstance).state    = new AntennaState(state);
        }
Esempio n. 4
0
 /// <summary>
 ///  Create a new state object to represent an organism.
 /// </summary>
 /// <param name="id">The GUID ID representing this organism in the world.</param>
 /// <param name="species">The species which defines the basic properties of the organism.</param>
 /// <param name="generation">The familial generation number.</param>
 /// <param name="initialEnergyState">The initial EnergyState of the organism.</param>
 /// <param name="initialRadius">The initial Radius of the organism.</param>
 internal OrganismState(string id, ISpecies species, int generation, EnergyState initialEnergyState, int initialRadius)
 {
     DeathReason = PopulationChangeReason.NotDead;
     ID          = id;
     Species     = species;
     Generation  = generation;
     SetStoredEnergyInternal(OrganismState.UpperBoundaryForEnergyState(species, initialEnergyState, initialRadius));
     Radius           = initialRadius;
     _events          = new OrganismEventResults();
     _currentPosition = new Point();
 }
Esempio n. 5
0
        /// <summary>
        ///  Used to compute whether or not a given state object is in an adjacent or
        ///  overlapping grid cell.  The extra radius can be used to extend the area
        ///  used for the function to find a match and so can be used for functions
        ///  like visibiliy.
        /// </summary>
        /// <param name="state1ExtraRadius">The amount of extra grid cells to add</param>
        /// <param name="state2">The organism state of the creature to use in the area test.</param>
        /// <returns>True if the creature is within range, false otherwise.</returns>
        public Boolean IsWithinRect(int state1ExtraRadius, OrganismState state2)
        {
            if (null == state2)
            {
                return(false);
            }

            var state1Radius = CellRadius + state1ExtraRadius;
            var state2Radius = state2.CellRadius;

            var difference = (GridX - state1Radius) - (state2.GridX - state2Radius);

            if (difference < 0)
            {
                // Negative means state1 boundary < state2 boundary
                if (-difference > (state1Radius * 2) + 1)
                {
                    // X isn't overlapping or adjacent
                    return(false);
                }
            }
            else
            {
                // state2 boundary <=  state1 boundary
                if (difference > (state2Radius * 2) + 1)
                {
                    // X isn't overlapping or adjacent
                    return(false);
                }
            }

            difference = (GridY - state1Radius) - (state2.GridY - state2Radius);
            if (difference < 0)
            {
                // Negative means state1 boundary < state2 boundary
                if (-difference > (state1Radius * 2) + 1)
                {
                    // Y isn't overlapping or adjacent
                    return(false);
                }
            }
            else
            {
                // state2 boundary <=  state1 boundary
                if (difference > (state2Radius * 2) + 1)
                {
                    // Y isn't overlapping or adjacent
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 6
0
        /// <summary>
        ///  <para>
        ///   Tries to return an updated OrganismState given a creature's state OrganismState.
        ///   This function may return null if the creature can't be found or was hidden by
        ///   camouflage.  You may call this method multiple times and get different results.
        ///  </para>
        /// </summary>
        /// <param name="organismState">
        ///  The stale OrganismState object you want to refresh.
        /// </param>
        /// <returns>
        ///  OrganismState representing the creature being looked for or null if not found.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the organismState parameter is null.
        /// </exception>
        public OrganismState LookFor(OrganismState organismState)
        {
            if (organismState == null)
            {
                throw new ArgumentNullException("organismState", "The argument 'organismState' cannot be null");
            }

            return World.LookFor(organismState);
        }
Esempio n. 7
0
        /// <summary>
        ///  <para>
        ///   Allows a creature to determine if the OrganismState of another creature
        ///   represents the same species.  This can be used to determine whether you
        ///   should attack/defend against another creature.
        ///  </para>
        ///  <para>
        ///   Creatures of the same species often don't fight one another, defend against
        ///   one another, and kill one another.  They often help their own species in
        ///   fights against other species.  Carnivores of the same species may sacrifice
        ///   themselves as food once they become too old to members of their species.
        ///  </para>
        /// </summary>
        /// <param name="targetState">
        ///  The OrganismState for the creature to be used in species comparison.
        /// </param>
        /// <returns>
        ///  True if the organism owning the state object is of the same species, false otherwise.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the targetState parameter is null.
        /// </exception>
        public Boolean IsMySpecies(OrganismState targetState)
        {
            if (targetState == null)
            {
                throw new ArgumentNullException("targetState", "The argument 'targetState' cannot be null");
            }

            return State.Species.IsSameSpecies(targetState.Species);
        }
Esempio n. 8
0
        /// <summary>
        ///  <para>
        ///   Method used to command your creature to start eating another creature.
        ///   You can only eat one target creature per round, and a single call to
        ///   BeginEating will only attack a target creature in the upcoming tick.
        ///   Calling BeginEating multiple times in the same turn will only result
        ///   in your creature eating the target specified in the last call to
        ///   BeginEating.
        ///  </para>
        ///  <para>
        ///   Eating is asynchronous so you'll need to handle the EatCompleted event
        ///   in order to get the status of the bite.  A single bite might not
        ///   produce enough energy for your creature so you'll have to make multiple
        ///   bites against the same target until it is completed eaten.
        ///  </para>
        /// </summary>
        /// <param name="targetOrganism">
        ///  OrganismState of the creature you wish to eat.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the targetOrganism parameter is null.
        /// </exception>
        /// <exception cref="AlreadyFullException">
        ///  Thrown if your creature is not hungry enough to eat.
        /// </exception>
        /// <exception cref="NotVisibleException">
        ///  Thrown if the creature had disappeared from your creature's view.
        /// </exception>
        /// <exception cref="NotWithinDistanceException">
        ///  Thrown if your creature is not within eating distance.
        /// </exception>
        /// <exception cref="ImproperFoodException">
        ///  Thrown if a Carnivore tries to eat a plant or a Herbivore tries to eat an Animal
        /// </exception>
        /// <exception cref="NotDeadException">
        ///  Thrown if a Carnivore tries to eat a creature that isn't dead yet.
        /// </exception>
        public void BeginEating(OrganismState targetOrganism)
        {
            if (targetOrganism == null)
            {
                throw new ArgumentNullException("targetOrganism", "The argument 'targetOrganism' cannot be null");
            }

            if (State.EnergyState > EnergyState.Normal)
            {
                throw new AlreadyFullException();
            }

            // Get an up to date state -- this organism may be an old state
            var currentOrganism = World.LookForNoCamouflage(targetOrganism);

            if (currentOrganism == null)
            {
                throw new NotVisibleException();
            }
            if (!WithinEatingRange(currentOrganism))
            {
                throw new NotWithinDistanceException();
            }

            // Make sure it is edible
            if (State.AnimalSpecies.IsCarnivore)
            {
                if (currentOrganism is PlantState)
                {
                    throw new ImproperFoodException();
                }

                if (currentOrganism.IsAlive)
                {
                    throw new NotDeadException();
                }
            }
            else
            {
                if (currentOrganism is AnimalState)
                {
                    throw new ImproperFoodException();
                }
            }

            var actionID = GetNextActionID();
            var action = new EatAction(ID, actionID, targetOrganism);
            lock (PendingActions)
            {
                PendingActions.SetEatAction(action);
                InProgressActions.SetEatAction(action);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newInstance"></param>
        protected override void CopyStateInto(OrganismState newInstance)
        {
            base.CopyStateInto(newInstance);

            ((AnimalState)newInstance).damage = damage;
            ((AnimalState)newInstance).RotTicks = RotTicks;
            ((AnimalState)newInstance).state = new AntennaState(state);
        }
Esempio n. 10
0
 /// <summary>
 ///  <para>
 ///   Determines if a creature is immediately next to or overlapping
 ///   another creature using grid cells comparisons.
 ///  </para>
 /// </summary>
 /// <param name="state2">
 ///  OrganismState of the creature to check for proximity.
 /// </param>
 /// <returns>
 ///  True if the creature is adjacent or overlapping, False otherwise.
 /// </returns>
 public Boolean IsAdjacentOrOverlapping(OrganismState state2)
 {
     return IsWithinRect(0, state2);
 }
Esempio n. 11
0
 /// <summary>
 ///  <para>
 ///   Determines if a creature is immediately next to or overlapping
 ///   another creature using grid cells comparisons.
 ///  </para>
 /// </summary>
 /// <param name="state2">
 ///  OrganismState of the creature to check for proximity.
 /// </param>
 /// <returns>
 ///  True if the creature is adjacent or overlapping, False otherwise.
 /// </returns>
 public Boolean IsAdjacentOrOverlapping(OrganismState state2)
 {
     return(IsWithinRect(0, state2));
 }
Esempio n. 12
0
 /// <summary>
 ///  Create a new eat action to eat a specific organism.
 /// </summary>
 /// <param name="organismID">Eating organism's ID</param>
 /// <param name="actionID">Unique Organism ID for action.</param>
 /// <param name="targetOrganism">The state representing the organism to eat.</param>
 internal EatAction(string organismID, int actionID, OrganismState targetOrganism)
     : base(organismID, actionID)
 {
     TargetOrganism = targetOrganism;
 }
Esempio n. 13
0
        /// <summary>
        ///  Copies the value of the current state into a new state object.
        ///  Used by the CloneMutable method to make mutable copies of state
        ///  objects.
        /// </summary>
        /// <param name="newInstance">The new state object that will hold the values.</param>
        /// <internal/>
        protected override void CopyStateInto(OrganismState newInstance)
        {
            base.CopyStateInto(newInstance);

            ((PlantState)newInstance).Height = Height;
        }
Esempio n. 14
0
        /// <summary>
        ///  Copies the value of the current state into a new state object.
        ///  Used by the CloneMutable method to make mutable copies of state
        ///  objects.
        /// </summary>
        /// <param name="newInstance">The new state object that will hold the values.</param>
        /// <internal/>
        protected override void CopyStateInto(OrganismState newInstance)
        {
            base.CopyStateInto(newInstance);

            ((PlantState)newInstance).Height = Height;
        }
Esempio n. 15
0
        /// <summary>
        ///  Used to compute whether or not a given state object is in an adjacent or
        ///  overlapping grid cell.  The extra radius can be used to extend the area
        ///  used for the function to find a match and so can be used for functions
        ///  like visibiliy.
        /// </summary>
        /// <param name="state1ExtraRadius">The amount of extra grid cells to add</param>
        /// <param name="state2">The organism state of the creature to use in the area test.</param>
        /// <returns>True if the creature is within range, false otherwise.</returns>
        public Boolean IsWithinRect(int state1ExtraRadius, OrganismState state2)
        {
            if (null == state2)
            {
                return false;
            }

            var state1Radius = CellRadius + state1ExtraRadius;
            var state2Radius = state2.CellRadius;

            var difference = (GridX - state1Radius) - (state2.GridX - state2Radius);
            if (difference < 0)
            {
                // Negative means state1 boundary < state2 boundary
                if (-difference > (state1Radius * 2) + 1)
                {
                    // X isn't overlapping or adjacent
                    return false;
                }
            }
            else
            {
                // state2 boundary <=  state1 boundary
                if (difference > (state2Radius * 2) + 1)
                {
                    // X isn't overlapping or adjacent
                    return false;
                }
            }

            difference = (GridY - state1Radius) - (state2.GridY - state2Radius);
            if (difference < 0)
            {
                // Negative means state1 boundary < state2 boundary
                if (-difference > (state1Radius * 2) + 1)
                {
                    // Y isn't overlapping or adjacent
                    return false;
                }
            }
            else
            {
                // state2 boundary <=  state1 boundary
                if (difference > (state2Radius * 2) + 1)
                {
                    // Y isn't overlapping or adjacent
                    return false;
                }
            }

            return true;
        }
Esempio n. 16
0
        /// <summary>
        ///  <para>
        ///   Used to determine if your creature is within range to eat another
        ///   target creature.
        ///  </para>
        ///  <para>
        ///   This method does not attempt to validate the position of the
        ///   organismState with respect to the current world state.  If you
        ///   pass a stale object in then you may get stale results.  Make sure
        ///   you use the LookFor method to get the most up-to-date results.
        ///  </para>
        /// </summary>
        /// <param name="targetOrganism">
        ///  OrganismState of the creature you're thinking of eating.
        /// </param>
        /// <returns>
        ///  True if the creature is within range to eat, False otherwise.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the targetOrganism parameter is null.
        /// </exception>
        public Boolean WithinEatingRange(OrganismState targetOrganism)
        {
            if (targetOrganism == null)
            {
                throw new ArgumentNullException("targetOrganism", "The argument 'targetOrganism' cannot be null");
            }

            return State.IsAdjacentOrOverlapping(targetOrganism);
        }
Esempio n. 17
0
        /// <summary>
        ///  <para>
        ///   Calculates the linear distance between your creature and another using
        ///   various API's defined by the Vector class.
        ///  </para>
        /// </summary>
        /// <param name="organismState">
        /// The OrganismState object for the creature to
        /// use when computing linear distance from you're creature.
        /// </param>
        /// <returns>
        /// A System.Double representing the linear distance between your creature and another.
        /// </returns>
        public double DistanceTo(OrganismState organismState)
        {
            if (organismState == null)
            {
                throw new ArgumentNullException("organismState", "The argument 'organismState' cannot be null");
            }

            return Vector.Subtract(Position, organismState.Position).Magnitude;
        }
Esempio n. 18
0
        /// <summary>
        ///  Derived classes must override (and call Base.CopyStateInto)
        ///  if they have additional state
        /// </summary>
        /// <param name="newInstance">The new state that will hold this state's members</param>
        /// <internal/>
        protected virtual void CopyStateInto(OrganismState newInstance)
        {
            // OrganismID and species are copied via the constructor
            newInstance.Radius = Radius;

            // Safe because they are immutable
            newInstance._currentMoveToAction = _currentMoveToAction;
            newInstance._currentReproduceAction = _currentReproduceAction;

            // Points aren't immutable, so return a copy
            newInstance._currentPosition = new Point(_currentPosition.X, _currentPosition.Y);

            newInstance._energy = _energy;
            newInstance.currentFoodChunks = currentFoodChunks;
            newInstance.IncubationTicks = IncubationTicks;
            newInstance.TickAge = TickAge;
            newInstance.ReproductionWait = ReproductionWait;
            newInstance.GrowthWait = GrowthWait;
            newInstance.DeathReason = DeathReason;
            newInstance.ActualDirection = ActualDirection;

            // This object remains mutable because it is information
            // that the renderer updates after the WorldVector has been
            // created.  Nothing besides the renderer should ever touch this
            newInstance.RenderInfo = RenderInfo;
        }