public void Update(GameTime gameTime) { if (IsDead) return; if (currentPosition.X < 0) { currentPosition.X += SCALE_FACTOR; } else if (currentPosition.X > SCALE_FACTOR) { currentPosition.X -= SCALE_FACTOR; } if (currentPosition.Y < 0) { currentPosition.Y += SCALE_FACTOR; } else if (currentPosition.Y > SCALE_FACTOR) { currentPosition.Y -= SCALE_FACTOR; } if ((this.NearestKnownWaterSource.HasValue) && (Vector2.DistanceSquared(currentPosition, NearestKnownWaterSource.Value) < 30000) && CurrentThirst < 100.0f) { CurrentThirst += 0.05f; } else { CurrentThirst -= 0.001f * characterProperties.thirstDecay; } if ((this.NearestKnownTempSource.HasValue) && (Vector2.DistanceSquared(currentPosition, NearestKnownTempSource.Value) < 30000)) { if (CurrentHotTemp < 100.0f) { CurrentHotTemp += 5.0f; } if (CurrentColdTemp < 100.0f) { CurrentColdTemp += 5.0f; } } else if ( (CurrentHotTemp < 80.0f) ) { if (RANDOM.Next(2) == 0) { CurrentHotTemp += (float) (RANDOM.NextDouble() * (0.05 * characterProperties.hotTempMultiplier)); //CurrentColdTemp += (float) (RANDOM.NextDouble() * (0.05 * characterProperties.coldTempMultiplier)); } else { CurrentHotTemp -= (float) (RANDOM.NextDouble() * (0.05 * characterProperties.hotTempMultiplier)); //CurrentColdTemp += (float) (RANDOM.NextDouble() * (0.05 * characterProperties.coldTempMultiplier)); } } else if (CurrentColdTemp < 80.0f) { if (RANDOM.Next(2) == 0) { //CurrentHotTemp += (float)(RANDOM.NextDouble() * (0.05 * characterProperties.hotTempMultiplier)); CurrentColdTemp += (float)(RANDOM.NextDouble() * (0.05 * characterProperties.coldTempMultiplier)); } else { //CurrentHotTemp += (float)(RANDOM.NextDouble() * (0.05 * characterProperties.hotTempMultiplier)); CurrentColdTemp -= (float)(RANDOM.NextDouble() * (0.05 * characterProperties.coldTempMultiplier)); } } if ((this.NearestKnownHealthSource.HasValue) && (Vector2.DistanceSquared(currentPosition, NearestKnownHealthSource.Value) < 30000) && CurrentHealth < 100.0f) { CurrentHealth += 0.05f; } else { } if ((this.NearestKnownFoodSource.HasValue) && (Vector2.DistanceSquared(currentPosition, NearestKnownWaterSource.Value) < 30000) && CurrentHunger < 100.0f) { CurrentHunger += 0.05f; } else { CurrentHunger -= (0.001f * characterProperties.hungerDecay); } Needs CurrentNeeds = new Needs(); CurrentNeeds.Cold = CurrentColdTemp; CurrentNeeds.Health = CurrentHealth; CurrentNeeds.Hot = CurrentHotTemp; CurrentNeeds.Thirst = CurrentThirst; CurrentNeeds.Hunger = CurrentHunger; bool HasUrgentNeeds = CurrentNeeds.AreUrgent(); float speedMultiplier = 0.0f; if (!HasUrgentNeeds && (Vector2.DistanceSquared(currentPosition, goal) > 64000)) { goal = DecisionProcessing.RandomGoal(currentPosition); } else { KnowledgeModel Knowledge = new KnowledgeModel(); Knowledge.ClosestWater = (NearestKnownWaterSource.HasValue) ? NearestKnownWaterSource.Value : (Vector2?)null; Knowledge.ClostestFood = (NearestKnownFoodSource.HasValue) ? NearestKnownFoodSource.Value : (Vector2?)null; Knowledge.ClosestMedicine = (NearestKnownHealthSource.HasValue) ? NearestKnownHealthSource.Value : (Vector2?)null; Knowledge.ClosestShelter = (NearestKnownTempSource.HasValue) ? NearestKnownTempSource.Value : (Vector2?)null; Knowledge.ClosestGameAction = (NearestInstructionDirection.HasValue) ? NearestInstructionDirection.Value : (Vector2?)null; goal = DecisionProcessing.Run(currentPosition, Knowledge, CurrentNeeds, CurrentBehaviour); speedMultiplier = 3.0f; } Vector2 direction = goal - currentPosition; if ((Vector2.DistanceSquared(goal, currentPosition) > 2.5)) { direction.Normalize(); currentPosition += (direction * speedMultiplier); } }
private static bool CanBeSatisfied(Vector2 CurrentPosition, Priority CurrentPriority, KnowledgeModel CurrentKnowledge) { const int DISTANCE = 25000; switch (CurrentPriority) { case (Priority.None): { return true; break; } case (Priority.Medicine): { return (CurrentKnowledge.ClosestMedicine.HasValue && (Vector2.DistanceSquared(CurrentPosition, CurrentKnowledge.ClosestMedicine.Value) < DISTANCE)) ; } case (Priority.Food): { return (CurrentKnowledge.ClostestFood.HasValue && (Vector2.DistanceSquared(CurrentPosition, CurrentKnowledge.ClostestFood.Value) < DISTANCE)); } case (Priority.Shelter): { return (CurrentKnowledge.ClosestShelter.HasValue && (Vector2.DistanceSquared(CurrentPosition, CurrentKnowledge.ClosestShelter.Value) < DISTANCE)); } case (Priority.Water): { return (CurrentKnowledge.ClosestWater.HasValue && (Vector2.DistanceSquared(CurrentPosition, CurrentKnowledge.ClosestWater.Value) < DISTANCE)); } default: { return false; } } }
private static Vector2 RunPriority(Priority CurrentPriority, KnowledgeModel CurrentKnowledge, Vector2 CurrentPosition) { switch (CurrentPriority) { case (Priority.Medicine): { return CurrentKnowledge.ClosestMedicine.Value; } case (Priority.Food): { return CurrentKnowledge.ClostestFood.Value; } case (Priority.Shelter): { return CurrentKnowledge.ClosestShelter.Value; } case (Priority.Water): { return CurrentKnowledge.ClosestWater.Value; } default: { return RandomGoal(CurrentPosition); } } }
public static Vector2 Run(Vector2 Position, KnowledgeModel Knowledge, Needs Needs, Behaviour Behaviour) { if (Knowledge.ClosestGameAction.HasValue && Behaviour == Behaviour.Conforming) { return (Vector2) Knowledge.ClosestGameAction; } bool IsSatisfied = false; Priority myPriority = GetPriority(Needs); for (int i = 1; (i < 5) && (IsSatisfied == false); i++) { if (CanBeSatisfied(Position, myPriority, Knowledge) == true) { IsSatisfied = true; break; } Needs.Eliminate(myPriority); myPriority = GetPriority(Needs); } if (IsSatisfied == false) { myPriority = Priority.None; } return RunPriority(myPriority, Knowledge, Position); }