Beispiel #1
0
        /// <summary>
        ///  <para>
        ///   Method used to command a creature to begin moving towards a specific location
        ///   at a specific speed.  The actual movement operation may take several turns,
        ///   but is always initiated using this method.  Your movement location should
        ///   be within the world boundary and your movement speed should be less than or
        ///   equal to your creature's Species.MaximumSpeed.
        ///  </para>
        ///  <para>
        ///   Once called the creature will begin moving towards the specified point.  This
        ///   movement will continue until you issue a different BeginMoving command to your
        ///   creature, it reaches its destination, or becomes blocked by something.  Any
        ///   calls to BeginMoving will clear out any previous calls, so care should be taken
        ///   when issuing multi-part path movements.
        ///  </para>
        ///  <para>
        ///   Once the movement is completed the MoveCompleted event will be fired and your
        ///   event handler for this function will be called if you've provided one.  The
        ///   event handler will provide full information about the results of an attempted
        ///   movement operation.
        ///  </para>
        /// </summary>
        /// <param name="vector">
        ///  The MovementVector that determines the point you are moving to and how fast to move there.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the vector parameter is null.
        /// </exception>
        /// <exception cref="OutOfBoundsException">
        ///  Thrown if the destination is outside of the world boundaries.
        /// </exception>
        /// <exception cref="TooFastException">
        ///  Thrown if the speed defined in the vector is greater than Species.MaximumSpeed.
        /// </exception>
        public void BeginMoving(MovementVector vector)
        {
            if (vector == null)
            {
                throw new ArgumentNullException("vector", "The argument 'vector' cannot be null");
            }

            if (vector.Speed > State.AnimalSpecies.MaximumSpeed)
            {
                throw new TooFastException();
            }

            if (vector.Destination.X > World.WorldWidth - 1 ||
                vector.Destination.X < 0 ||
                vector.Destination.Y > World.WorldHeight - 1 ||
                vector.Destination.Y < 0)
            {
                throw new OutOfBoundsException();
            }

            var actionID = GetNextActionID();
            var action   = new MoveToAction(ID, actionID, vector);

            lock (PendingActions)
            {
                PendingActions.SetMoveToAction(action);
                InProgressActions.SetMoveToAction(action);
            }
        }
Beispiel #2
0
        /// <summary>
        ///  <para>
        ///   Use this function to command your creature to reproduce.  There are many
        ///   conditions on whether your creature can reproduce.  If these conditions
        ///   are not met, an exception will be thrown.  The easiest way to make
        ///   sure all pre-existing conditions have been met is to check the CanReproduce
        ///   property.
        ///  </para>
        ///  <para>
        ///   If you call this method multiple times in the same turn, then the last call
        ///   will be used, and all previous calls will be ignored.  This method is also
        ///   asynchronous, and a ReproduceCompletedEvent will be fired when your creature
        ///   has actually given birth.  The time between start and completion is 10 ticks.
        ///  </para>
        /// </summary>
        /// <param name="dna">
        ///  A byte array that gets passed to the child.  This can be any information you
        ///  want to pass to the child creature.  The byte array is truncated at 8000 bytes.
        /// </param>
        /// <exception cref="AlreadyReproducingException">
        ///  Thrown when your creature is already in the process of reproduction.
        /// </exception>
        /// <exception cref="NotMatureException">
        ///  Thrown when your creature is not yet mature and you try to reproduce.
        /// </exception>
        /// <exception cref="NotEnoughEnergyException">
        ///  Thrown when your creature does not have enough energy to start reproduction.
        /// </exception>
        /// <exception cref="NotReadyToReproduceException">
        ///  Thrown when your creature is not yet ready to reproduce because the appropriate number of ticks has not elapsed.
        /// </exception>
        public void BeginReproduction(byte[] dna)
        {
            if (IsReproducing)
            {
                throw new AlreadyReproducingException();
            }

            if (!State.IsMature)
            {
                throw new NotMatureException();
            }

            if (State.EnergyState < EnergyState.Normal)
            {
                throw new NotEnoughEnergyException();
            }

            if (!State.ReadyToReproduce)
            {
                throw new NotReadyToReproduceException();
            }

            var actionID = GetNextActionID();
            var action   = new ReproduceAction(ID, actionID, dna);

            lock (PendingActions)
            {
                PendingActions.SetReproduceAction(action);
                InProgressActions.SetReproduceAction(action);
            }
        }
Beispiel #3
0
 /// <summary>
 ///  <para>
 ///   Clears any pending movement operations your creature might be performing.
 ///  </para>
 /// </summary>
 public void StopMoving()
 {
     lock (PendingActions)
     {
         PendingActions.SetMoveToAction(null);
         InProgressActions.SetMoveToAction(null);
     }
 }
Beispiel #4
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);
            }
        }
Beispiel #5
0
        /// <internal/>
        public PendingActions GetThenErasePendingActions()
        {
            PendingActions detachedActions;

            lock (PendingActions)
            {
                detachedActions = pendingActions;
                pendingActions  = new PendingActions();
            }
            detachedActions.MakeImmutable();
            return(detachedActions);
        }
Beispiel #6
0
        /// <summary>
        ///  <para>
        ///   Method used to command a creature to begin defending against a specific
        ///   target creature.  You can only defend against one creature at a time,
        ///   so only the final call to BeginDefending will actually be used
        ///   in the upcoming turn.
        ///  </para>
        ///  <para>
        ///   Once your creature has finished defending, the DefendCompleted event will
        ///   be fired and your event handler will be called if you provided one.  You
        ///   can use this event to determine the results of your defense.
        ///  </para>
        /// </summary>
        /// <param name="targetAnimal">
        ///  The AnimalState that represents the animal you want to defend against.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        ///  Thrown if the targetAnimal parameter is null.
        /// </exception>
        public void BeginDefending(AnimalState targetAnimal)
        {
            if (targetAnimal == null)
            {
                throw new ArgumentNullException("targetAnimal", "The argument 'targetAnimal' cannot be null");
            }

            var actionID = GetNextActionID();
            var action   = new DefendAction(ID, actionID, targetAnimal);

            lock (PendingActions)
            {
                PendingActions.SetDefendAction(action);
                InProgressActions.SetDefendAction(action);
            }
        }
Beispiel #7
0
 /// <internal/>
 public PendingActions GetThenErasePendingActions()
 {
     PendingActions detachedActions;
     lock (PendingActions)
     {
         detachedActions = pendingActions;
         pendingActions = new PendingActions();
     }
     detachedActions.MakeImmutable();
     return detachedActions;
 }