public override BehaviorStatus Update(Entity self, double dt) { BehaviorStatus status = base.Update(self, dt); CitizenComponent citizen; switch (status) { case BehaviorStatus.SUCCESS: case BehaviorStatus.FAIL: if (Finished is ExitBuildingBehavior) { ExitBuildingBehavior exit = (ExitBuildingBehavior)Finished; if (status == BehaviorStatus.SUCCESS) { // make sure the citizen starts at the right position PositionComponent position = self.Get <PositionComponent>(); Vector2 startAt = World.Map.GetPositionFromIndex(exit.SelectedPath.Start.X, exit.SelectedPath.Start.Y); position.X = startAt.X; position.Y = startAt.Y; position.Index = exit.SelectedPath.Start; GoToBehavior g2b = new GoToBehavior() { GeneratedPath = exit.SelectedPath, TargetID = exit.TargetID }; AddChild(g2b); } } else if (Finished is GoToBehavior) { if (status == BehaviorStatus.SUCCESS) { if (State == HaulerState.RETURNING) { // Add the items in out inventory to the stockpile Inventory selfInventory = self.Get <Inventory>(); // move item back to job inventory if (!string.IsNullOrWhiteSpace(CurrentItem) && selfInventory.Items[CurrentItem].Amount > 0) { citizen = self.Get <CitizenComponent>(); Inventory jobInventory = World.Entities.Get(citizen.JobID).Get <Inventory>(); jobInventory.Add(CurrentItem, selfInventory.Items[CurrentItem].Amount); selfInventory.Set(CurrentItem, 0); } State = HaulerState.DELIVERING; AddChild(new IdleBehavior() { IdleTime = 0.2 }); } else if (State == HaulerState.DELIVERING) { // Add the items in out inventory to the stockpile Inventory selfInventory = self.Get <Inventory>(); Entity se = World.Entities.Get(((GoToBehavior)Finished).TargetID); StockpileComponent stockpile = se.Get <StockpileComponent>(); int movedAmount = stockpile.AddToItem(CurrentItem, selfInventory.Items[CurrentItem].Amount); selfInventory.Add(CurrentItem, -movedAmount); State = HaulerState.RETURNING; AddChild(new IdleBehavior() { IdleTime = 0.2 }); } } } break; case BehaviorStatus.RUN: citizen = self.Get <CitizenComponent>(); if (State == HaulerState.RETURNING) { AddChild(new ExitBuildingBehavior() { ExitID = citizen.InsideID, TargetID = citizen.JobID }); } else if (State == HaulerState.DELIVERING) { Inventory jobInventory = World.Entities.Get(citizen.JobID).Get <Inventory>(); Inventory haulerInventory = self.Get <Inventory>(); if (jobInventory.Items.Values.ToList().Find(delegate(InventoryData d) { return(d.Output && d.Amount > 0); }) != null) { List <Entity> stockpiles = World.GetBuildingsWithinWalkableDistance <StockpileComponent>(citizen.JobID, 30); foreach (Entity se in stockpiles) { StockpileComponent stockpile = se.Get <StockpileComponent>(); foreach (InventoryData invItem in jobInventory.Items.Values) { if (!invItem.Output) { continue; } // do the delivery if (stockpile.IsAccepting(invItem.Item) && stockpile.Amount(invItem.Item) < stockpile.Maximum(invItem.Item) && invItem.Amount > 0) { int amount = Math.Min(invItem.Amount, HaulerCapacity); haulerInventory.Add(invItem.Item, amount); jobInventory.Add(invItem.Item, -amount); CurrentItem = invItem.Item; AddChild(new ExitBuildingBehavior() { ExitID = citizen.InsideID, TargetID = se.ID }); return(BehaviorStatus.WAIT); } } } } // if no delivery sleep for a bit AddChild(new IdleBehavior()); } break; } return(BehaviorStatus.WAIT); }
public override BehaviorStatus Update(Entity self, double dt) { BehaviorStatus status = base.Update(self, dt); switch (status) { // child returned a success case BehaviorStatus.SUCCESS: if (Finished is ExitBuildingBehavior) { ExitBuildingBehavior exit = (ExitBuildingBehavior)Finished; // make sure the citizen starts at the right position PositionComponent position = self.Get <PositionComponent>(); Vector2 startAt = World.Map.GetPositionFromIndex(exit.SelectedPath.Start.X, exit.SelectedPath.Start.Y); position.X = startAt.X; position.Y = startAt.Y; position.Index = exit.SelectedPath.Start; GoToBehavior g2b = new GoToBehavior() { GeneratedPath = exit.SelectedPath, TargetID = exit.TargetID }; AddChild(g2b); } break; case BehaviorStatus.FAIL: break; case BehaviorStatus.RUN: // look for a secondary behavior to do CitizenComponent citizen = self.Get <CitizenComponent>(); // TODO: need to implement "archetype" behaviors like: child, student, adult, retired etc // these top-level behaviors will manage the needs and invoke appropriate sub-behaviors // the citizen is homeless, find them a home! if (citizen.HousingID == 0 && PreviousBehavior.GetType() != typeof(FindHomeBehavior)) { AddChild(new FindHomeBehavior()); } else if (citizen.JobID == 0 && citizen.HousingID != 0 && PreviousBehavior.GetType() != typeof(FindJobBehavior)) { AddChild(new FindJobBehavior()); } else { // do the hauling job if (citizen.IsHauler && citizen.JobID != 0) { AddChild(new HaulerBehavior()); } // go to work //else if (citizen.JobID != -1 && PreviousBehavior.GetType() == typeof(IdleBehavior) && citizen.InsideID != citizen.JobID) //{ // state.Push(new ExitBuildingBehavior() { ExitID = citizen.InsideID, TargetID = citizen.JobID }); // PreviousBehavior = state.Peek(); //} // go home else if (citizen.HousingID != 0 && PreviousBehavior.GetType() == typeof(IdleBehavior) && citizen.InsideID != citizen.HousingID) { AddChild(new ExitBuildingBehavior() { ExitID = citizen.InsideID, TargetID = citizen.HousingID }); } else { AddChild(new IdleBehavior()); } } PreviousBehavior = Child; break; } return(BehaviorStatus.RUN); }