public static BTStatus SleepNearLeader(Animal agent) { var leader = GetLeader(agent); if (leader == null || leader == agent) { return(BTStatus.Failure); } if (leader.AnimationState == AnimalAnimationState.Sleeping) { // sleep near alpha if (Vector3.WrappedDistance(agent.Position, leader.Position) < agent.Species.HeadDistance * 3) { agent.SetState(AnimalAnimationState.LyingDown, 10f); agent.Hunger = Math.Min(agent.Hunger, 50); return(BTStatus.Success); } // TODO: avoid overlapping with other herd members, make the leader pick a spot to sleep that can accomidate the herd var route = AIUtilities.GetRouteFacingTarget(agent.Position, leader.Position, agent.Species.WanderingSpeed, agent.Species.HeadDistance * 2); agent.Target.SetPath(route); agent.NextTick = agent.Target.TargetTime; agent.AnimationState = AnimalAnimationState.Wander; return(BTStatus.Success); } return(BTStatus.Failure); }
public static BTStatus TryEatNearbyCorpses(Animal agent) { Animal targetCorpse = null; if (agent.TryGetMemory <Animal>("targetCorpse", out targetCorpse) && !targetCorpse.Active) { targetCorpse = null; agent.Brain.Memory.Remove("targetCorpse"); } if (targetCorpse == null) { foreach (var corpse in Animal.Corpses.Shuffle()) { if (!corpse.Active) { Animal.Corpses.Remove(corpse); } else if (Vector3.WrappedDistance(corpse.Position, agent.Position) < 40 && agent.Species.Eats(corpse.Species)) { targetCorpse = corpse; agent.Brain.Memory["targetCorpse"] = targetCorpse; break; } } } if (targetCorpse != null) { if (agent.AnimationState == AnimalAnimationState.Eating) { // finished eating, go do something else agent.Hunger = 0; agent.Brain.Memory.Remove("targetCorpse"); return(BTStatus.Failure); } // eat or walk then eat agent.AnimationState = AnimalAnimationState.Eating; if (Vector3.WrappedDistance(targetCorpse.Position, agent.Position) < 3) { agent.NextTick = WorldTime.Seconds + 10f; agent.Target.Set(targetCorpse); return(BTStatus.Success); } else { var route = AIUtilities.GetRouteFacingTarget(agent.Position, targetCorpse.Position, agent.Species.WanderingSpeed, agent.Species.HeadDistance); agent.Target.SetPath(route); agent.Target.Set(targetCorpse); agent.NextTick = agent.Target.TargetTime + 20f; return(BTStatus.Success); } } return(BTStatus.Failure); }