public override BTResult Tick () { if (_previousResult != BTResult.Running || reevaludateEveryTick) { switch (logicOpt) { case BTLogic.And: int i = 0; foreach (BTConditional conditional in _conditionals) { bool invert = _conditionalInverts[i++]; if ((invert && conditional.Check()) || (!invert && !conditional.Check())) { return BTResult.Failed; } } break; case BTLogic.Or: bool anySuccess = false; i = 0; foreach (BTConditional conditional in _conditionals) { bool invert = _conditionalInverts[i++]; if ((invert && !conditional.Check()) || (!invert && conditional.Check())) { anySuccess = true; break; } } if (!anySuccess) { return BTResult.Failed; } break; } } _previousResult = child.Tick(); if (_previousResult == BTResult.Running) { isRunning = true; } return _previousResult; }
public override BTResult OnTick(BTBlackBoard blackBoard) { FP deltaTime = blackBoard.deltaTime; if (m_bIsEnd) { m_bIsEnd = false; m_sTime = 0; m_nCount = 0; } int count = m_lstChild.Count; for (int i = 0; i < count; i++) { if (m_lstResults[i] == BTResult.Running) { BTNode child = m_lstChild[i]; IBTTimeLineNode timeLineNode = child as IBTTimeLineNode; if (timeLineNode.time <= m_sTime) { BTResult result = child.OnTick(blackBoard); if (result != BTResult.Running) { m_lstResults[i] = result; m_nCount++; } } } } m_sTime += deltaTime; if (m_nCount == count) { m_bIsEnd = true; return(BTResult.Success); } return(BTResult.Running); }
static BTResult DoSleepNearLeader(Behavior <Animal> beh, Animal agent) { var leader = GetLeader(agent); if (leader == null) { return(BTResult.Failure("No leader")); } if (leader == agent) { return(BTResult.Failure("We are leader")); } //If the leader is sleeping... if (leader.State == AnimalState.Sleeping) { // and we're already close enough, sleep now. if (Vector3.WrappedDistance(agent.Position, leader.Position) < agent.Species.HeadDistance * 3) { return(agent.ChangeState(AnimalState.LyingDown, 60f, true)); } //Otherwise, move to them to sleep. // TODO: avoid overlapping with other herd members, make the leader pick a spot to sleep that can accommodate the herd var routeProps = new RouteProperties { MaxTargetLocationHeightDelta = agent.Species.ClimbHeight }; var route = AIUtil.GetRouteFacingTarget(agent.FacingDir, agent.Position, leader.Position, agent.Species.GetTraversalData(true), agent.Species.HeadDistance * 2, routeProps: routeProps); if (!route.IsValid) { return(BTResult.Failure("can't get route to leader")); } agent.SetRoute(route, AnimalState.Wander); return(BTResult.Success("walking to sleep near leader")); } return(BTResult.Failure("leader not sleeping")); }
public override BTResult Tick() { int numRunningChildren = 0; for (int i = 0; i < _children.Count; i++) { bool active = _activeList[i]; if (active) { BTResult result = _children[i].Tick(); if (result == BTResult.Running) { numRunningChildren++; } } } if (numRunningChildren == 0) { return(BTResult.Ended); } return(BTResult.Running); }
protected override BTResult OnCompositeTick(BTBlackBoard blackBoard) { int curIndex = m_iSelectedIndex; int selectedCount = 0; int totalCount = m_lstChild.Count; while (selectedCount < totalCount) { curIndex = curIndex % totalCount; var child = m_lstChild[curIndex]; BTResult childResult = this.OnRunningChildTick(child, blackBoard); if (childResult == BTResult.Failure) { curIndex++; selectedCount++; } else { m_iSelectedIndex = curIndex; return(childResult); } } return(BTResult.Failure); }
public override BTResult Exit(BTResult result) { Debug.Log("BTGetNextNode: " + result + " for party " + MyParty.PartyNumber); return(result); }
public override BTResult Exit(BTResult result) { MyAI.Whiteboard.Parameters["EvadeDir"] = Vector3.zero; MyAI.Whiteboard.Parameters["IsThrusting"] = false; return(result); }
public override BTResult Exit(BTResult result) { Debug.Log("BTGoToLocation: " + result); return(result); }
public static IEnumerator <BTResult> FindAndEatSomething(Animal agent, Behavior <Animal> noNearbyFoodBehavior, Func <IEnumerable <Vector3> > getFoodSources, float hungerRestoredPerEat) { var lastFoodSearchPos = Vector3.Zero; var foodSources = new Queue <Vector3>(); //While we're still hungry and don't have prey while (agent.Hunger > Brain.HungerToStopEating) { foodSources.Clear(); while (foodSources.Count == 0) { //Look for food sources, if we havent checked already and found it empty or just killed an enemy animal if (Vector3.WrappedDistance(lastFoodSearchPos, agent.Position) > 10 || (agent.TryGetMemory(Animal.IsAnimalKilledMemory, out bool isKilled) && isKilled)) { foodSources.AddRange(getFoodSources()); lastFoodSearchPos = agent.Position; agent.RemoveMemory(Animal.IsAnimalKilledMemory); } else //None found, get outta here { yield return(new BTResult(noNearbyFoodBehavior.Do(agent), "No food in 10m radius of last query. Moving till we're > 10m from last query.")); } } //Food sources available, find paths to them. var routeProps = new RouteProperties() { MaxTargetLocationHeightDelta = agent.Species.ClimbHeight }; while (foodSources.Count > 0 && Vector3.WrappedDistance(lastFoodSearchPos, agent.Position) < 10) { // Low-effort search for the first option or any other option visited while trying to hit the first with randomizing it in that area var route = AIUtil.GetRouteToAny(agent.FacingDir, agent.Position, foodSources, agent.Species.GetTraversalData(true), out var targetPosition, 100, 20, agent.Species.HeadDistance, routeProps); var target = targetPosition.Round; var distanceToTarget = Vector3.WrappedDistanceSq(agent.Position, target); // Move to target if it's far away if (distanceToTarget > 2f) { if (!route.HasValue) { break; } agent.SetRoute(route.Value, AnimalState.LookingForFood, route.Value.EndPosition.Round); yield return(BTResult.RunningChanged("walking to food")); // Stop walking to food if the distance to it has changed or it disappeared var agentTarget = agent.Target; if (agentTarget == null || Vector3.WrappedDistanceSq(agentTarget.Value, target) > 2f) { break; } } // Start eating food if it's close to us if (Vector3.WrappedDistanceSq(target, agent.Position) <= 2f) { agent.ClearRoute(); agent.LookAt(target); agent.ChangeState(AnimalState.Eating, 5, false); agent.Hunger -= hungerRestoredPerEat; yield return(BTResult.RunningChanged("chowing down")); agent.LookAt(null); lastFoodSearchPos = Vector3.Zero; //Don't actually destroy the plant, because that's handled in the world layer simulation. //var plant = EcoSim.PlantSim.GetPlant(targetPlantPosition.WorldPosition3i + Vector3i.Up); //if (plant != null) EcoSim.PlantSim.DestroyPlant(plant, DeathType.EatenByAnimal); } } } }
sealed public override BTResult OnTick(BTBlackBoard blackBoard) { BTResult result = OnEnter(blackBoard); return(Decorate(blackBoard, result)); }
public BTResult Tick(ref BTInput _input) { BTResult result = OnTick(ref _input); return(result); }
public abstract BTResult Exit(BTResult result);
public BTResult Run() { BTResult result = RootNode.Process(); return(result); }
public override void Clear () { if ((isRunning && clearOpt == ClearChildOpt.OnAbortRunning) || (_previousResult == BTResult.Success && clearOpt == ClearChildOpt.OnStopRunning) || clearOpt == ClearChildOpt.OnNotRunning) { isRunning = false; child.Clear(); } if (clearTick != null) { clearTick.Tick(); } _previousResult = BTResult.Failed; }
public override BTResult Exit(BTResult result) { _followTarget = null; return(result); }
public override void Clear() { if ((isRunning && clearOpt == ClearChildOpt.OnAbortRunning) || (_previousResult == BTResult.Success && clearOpt == ClearChildOpt.OnStopRunning) || clearOpt == ClearChildOpt.OnNotRunning) { isRunning = false; child.Clear(); } if (clearTick != null) { clearTick.Tick(); } //清除BTConditional foreach (BTConditional conditional in _conditionals) { if (conditional != null) conditional.Clear(); } _previousResult = BTResult.Failed; }
public override BTResult Exit(BTResult result) { //Debug.Log("Go to friendly " + result + " " + MyAI.MyShip.name); return(result); }
public BTDecorator() { this.name = "DefaultDecorator"; this.state = BTResult.Ready; }
protected virtual void OnExit(BTInput _input, BTResult _status) { }
public BTNode() { this.name = "Root"; this.State = BTResult.Ready; this.childrenNotes = new List <ITickNode>(); }
public static BTResult AmphibiousMovement(Animal agent, Vector2 generalDirection, bool wandering, AnimalState state, float minDistance = 2f, float maxDistance = 20f) { var startPathPos = agent.Position.WorldPosition3i; //Plop us into water if we're above it. if (World.World.GetBlock((Vector3i)startPathPos.Down()).GetType() == typeof(WaterBlock)) { startPathPos = startPathPos.Down(); } if (!World.World.IsUnderwater(startPathPos)) { startPathPos = RouteManager.NearestWalkablePathPos(agent.Position.WorldPosition3i); //Boot us down/up to the surface if we're on land. } if (!startPathPos.IsValid) { return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance)); } generalDirection = generalDirection == Vector2.zero ? Vector2.right.Rotate(RandomUtil.Range(0f, 360)) : generalDirection.Normalized; // Take random ground position in the given direction var targetGround = (agent.Position + (generalDirection * RandomUtil.Range(minDistance, maxDistance)).X_Z()).WorldPosition3i; // Floating animals will stick to water surface or land, non floating - land or return to swimming state if (World.World.IsUnderwater(targetGround) && agent.Species.FloatOnSurface) { targetGround.y = World.World.MaxWaterHeight[targetGround]; } else { targetGround = RouteManager.NearestWalkableXYZ(targetGround, 5); if (!agent.Species.FloatOnSurface && !targetGround.IsValid) { agent.Floating = false; return(BTResult.Failure("Can't float, continue swimming")); } } // This is a low-effort search that includes water surface and should occasionally fail, just pick a semi-random node that was visited when it fails var routeProps = new RouteProperties() { MaxTargetLocationHeightDelta = agent.Species.ClimbHeight }; var allowWaterSearch = new AStarSearch(RouteCacheData.NeighborsIncludeWater, agent.FacingDir, startPathPos, targetGround, 30, routeProps, false); if (allowWaterSearch.Status != SearchStatus.PathFound) { targetGround = allowWaterSearch.GroundNodes.Last().Key; allowWaterSearch.GetPathToWaterPos(targetGround); } // Apply land movement only for land positions if (!World.World.IsUnderwater(agent.Position.WorldPosition3i)) { if (allowWaterSearch.GroundPath.Count < 2) { return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance, skipRouteProperties: true)); } if (allowWaterSearch.Status == SearchStatus.Unpathable && allowWaterSearch.GroundNodes.Count < RouteRegions.MinimumRegionSize) { // Search region was unexpectedly small and agent is on land, might be trapped by player construction. // Try regular land movement so region checks can apply & the agent can get unstuck (or die) return(LandMovement(agent, generalDirection, wandering, state, minDistance, maxDistance)); } } var smoothed = allowWaterSearch.LineOfSightSmoothWaterPosition(agent.GroundPosition); var route = new Route(agent.Species.GetTraversalData(wandering), agent.FacingDir, smoothed); if (!route.IsValid) { route = Route.Basic(agent.Species.GetTraversalData(wandering), agent.FacingDir, agent.GroundPosition, route.EndPosition); } var routeTime = agent.SetRoute(route, state, null); return(routeTime < float.Epsilon ? BTResult.Failure("route not set") : BTResult.Success($"swimming path")); }
public override BTResult Exit(BTResult result) { //Debug.Log("Chase enemy result " + result); return(result); }
public override void OnEnter(BInput input) { this.m_iRunningIndex = 0; this.m_eResult = BTResult.SUCCESS; }
public override BTResult Exit(BTResult result) { return(result); }
public override BTResult Exit(BTResult result) { Debug.Log("BTGetNewTask: " + result); return(result); }
public virtual BTResult Decorate(BTBlackBoard bloackBoard, BTResult result) { return(result); }
public override BTResult Exit(BTResult result) { _undockSession = null; return(result); }
public BNode() { //this.nodeParent = null; this.m_eState = BTResult.NONE; }
public override BTResult Exit(BTResult result) { MyAI.Whiteboard.Parameters["IsEngineKilled"] = false; MyAI.Whiteboard.Parameters["IsThrusting"] = false; return(result); }