private void RemoveComponentsNotProposedBySystem(ProductionComponent requestComponent, AllocationRequestResult resolutions, Amount requiredAmount) { for (var i = requestComponent.Resolutions.Count - 1; i >= 0; i--) { var clientResolution = requestComponent.Resolutions[i]; var dbAllocation = resolutions.Allocations.FirstOrDefault(a => a.BatchNumber.Equals(clientResolution.BatchNumber, StringComparison.InvariantCultureIgnoreCase)); if (dbAllocation == null) { // we received allocation which was not proposed by the system requestComponent.Resolutions.RemoveAt(i); continue; } if ((clientResolution.GetAmount(m_unitRepository) == null) || m_amountProcessor.GreaterThan( clientResolution.GetAmount(m_unitRepository), dbAllocation.TotalBatchNumberAvailable)) { // this is an invalid allocation received from client var convertedMaxAvailable = m_amountProcessor.Convert(dbAllocation.TotalBatchNumberAvailable, requiredAmount.Unit); clientResolution.Amount = convertedMaxAvailable.Value; clientResolution.UnitSymbol = convertedMaxAvailable.Unit.Symbol; } } }
private void AddMissingComponents(ProductionComponent requestComponent, AllocationRequestResult resolutions, Amount requiredAmount, bool isSegmentUpdateFirstRound) { var clientComponentsCount = requestComponent.Resolutions.Count; foreach (var resolution in resolutions.Allocations) { var clientAllo = requestComponent.Resolutions.FirstOrDefault(a => a.BatchNumber.Equals(resolution.BatchNumber, StringComparison.InvariantCultureIgnoreCase)); if (clientAllo == null) { var convertedAllocatedAmount = m_amountProcessor.Convert(resolution.Allocated, requiredAmount.Unit); var convertedAvailableAmount = m_amountProcessor.Convert(resolution.TotalBatchNumberAvailable, requiredAmount.Unit); requestComponent.Resolutions.Add(new ProductionComponentResolution { Amount = isSegmentUpdateFirstRound ? 0m : convertedAllocatedAmount.Value, BatchAvailableAmount = convertedAvailableAmount.Value, BatchAvailableAmountText = convertedAvailableAmount.ToString(), UnitSymbol = convertedAllocatedAmount.Unit.Symbol, BatchCreationDt = StringUtil.FormatDate(resolution.BatchCreated), BatchNumber = resolution.BatchNumber, Sorter = resolution.BatchCreated.Ticks, Key = Guid.NewGuid().ToString() }); } } if ((clientComponentsCount > 0) && (requestComponent.Resolutions.Count > clientComponentsCount)) { requestComponent.Resolutions.Sort((a, b) => a.Sorter.CompareTo(b.Sorter)); } }
private static void ClearUserAllocationsIfQuantityChanged(ProductionComponent requestComponent, Amount requiredAmount) { if (!requiredAmount.ToString().Equals(requestComponent.LastClientAmount ?? string.Empty)) { requestComponent.Resolutions.Clear(); requestComponent.LastClientAmount = requiredAmount.ToString(); } }
public void ApplyComponents(MaterialBatchComponent sourceSegment, ProductionRequestContext context) { var recipeComponents = m_recipeRepository.GetRecipe(sourceSegment.Batch.RecipeId.Ensure("Segment nevznikl z existující receptury, nelze změnit")).Components.OrderBy(c => c.SortOrder); var requestComponents = context.Request.Components; foreach (var recipeComponent in recipeComponents) { var compo = new ProductionComponent { MaterialId = recipeComponent.MaterialId, MaterialName = m_materialRepository.GetMaterialById(recipeComponent.MaterialId).Ensure().Name, SortOrder = recipeComponent.SortOrder }; requestComponents.Add(compo); var resolutions = sourceSegment.Components.Where(c => c.Batch.MaterialId == recipeComponent.MaterialId); var resIndex = new Dictionary <string, ProductionComponentResolution>(); var componentUnit = m_unitRepository.GetUnit(recipeComponent.UnitId); foreach (var r in resolutions) { var resolutionAmount = m_amountProcessor.Convert(new Amount(r.ComponentAmount, r.ComponentUnit), componentUnit); var batchAvailability = m_amountProcessor.Convert(m_batchFacade.GetAvailableAmount(r.Batch.Id), componentUnit); if (!resIndex.TryGetValue(r.Batch.BatchNumber, out var resolution)) { resolution = new ProductionComponentResolution { Amount = resolutionAmount.Value, BatchAvailableAmount = batchAvailability.Value, BatchAvailableAmountText = batchAvailability.ToString(), BatchCreationDt = StringUtil.FormatDate(r.Batch.Created), BatchNumber = r.Batch.BatchNumber, Key = Guid.NewGuid().ToString(), Sorter = r.Batch.Created.Ticks, UnitSymbol = componentUnit.Symbol }; compo.Resolutions.Add(resolution); resIndex.Add(r.Batch.BatchNumber, resolution); } else { resolution.Amount += resolutionAmount.Value; } } compo.LastClientAmount = m_amountProcessor .Sum(compo.Resolutions.Select(r => r.GetAmount(m_unitRepository)))?.ToString(); } }
public void Process(ProductionRequestContext context) { var recipeComponentList = context.Recipe.Components.OrderBy(c => c.SortOrder).ToList(); for (var i = context.Request.Components.Count - 1; i >= 0; i--) { // kick out components not required by the recipe if (recipeComponentList.All(m => m.MaterialId != context.Request.Components[i].MaterialId)) { context.Request.Components.RemoveAt(i); } } var before = DateTime.Now; if (context.Request.SourceSegmentId != null) { var batch = m_batchRepository.GetBatchById(context.Request.SourceSegmentId.Value).Ensure(); before = batch.Batch.Created; } foreach (var recipeComponent in recipeComponentList) { var requestComponent = context.Request.Components.SingleOrDefault(c => c.MaterialId == recipeComponent.MaterialId); if (requestComponent == null) { requestComponent = new ProductionComponent { IsValid = true, MaterialId = recipeComponent.MaterialId, MaterialName = m_materialRepository.GetMaterialById(recipeComponent.MaterialId).Name }; context.Request.Components.Add(requestComponent); } requestComponent.RequiredAmount = recipeComponent.Amount * context.ComponentMultiplier; requestComponent.UnitSymbol = m_unitRepository.GetUnit(recipeComponent.UnitId).Symbol; requestComponent.SortOrder = recipeComponent.SortOrder; ProcessResolutions(context.Request, recipeComponent, requestComponent, context.ComponentMultiplier, before); } context.Request.Components.Sort( new Comparison <ProductionComponent>((a, b) => a.SortOrder.CompareTo(b.SortOrder))); }
public override BehaviorStatus Update(Entity self, double dt) { CitizenComponent citizen = self.Get <CitizenComponent>(); List <Entity> potentialJobs = World.GetBuildingsWithinWalkableDistance <ProductionComponent>(citizen.HousingID, 20); foreach (Entity e in potentialJobs) { ProductionComponent production = e.Get <ProductionComponent>(); // make sure there are jobs available here if (production.Employees.Length >= production.MaxEmployees) { continue; } // see if the job hires the appropriate gender if (production.EmployeeGender != Gender.BOTH && production.EmployeeGender != citizen.Gender) { continue; } // take the job // TODO: make sure the employee can path to the job if (production.AddEmployee(self)) { citizen.JobID = e.ID; if (production.MaxHaulers > 0) { citizen.IsHauler = production.AddHauler(self); if (citizen.IsHauler) { self.AddComponent(new Inventory()); // add an inventory to the hauler } } return(BehaviorStatus.SUCCESS); } } return(BehaviorStatus.FAIL); }
public ProductionFrame(ProductionComponent source) : base(1, 3) { padding_ = new Vector2(5); source_ = source; buttons_ = new ItemButton[2]; for (int index = 0; index < 2; ++index) { buttons_[index] = new ItemButton(source_, index); buttons_[index].getSource = getSource; buttons_[index].getComponent = getComponent; buttons_[index].getTarget = source_.getItem; } bar_ = new ProgressBar(); set(0, 0, buttons_[0]); set(0, 1, bar_); set(0, 2, buttons_[1]); refresh(); source_.register(refresh); }
private static bool TryProcessTransformationInput(ProductionRequest request, IRecipeComponent recipeComponent, ProductionComponent requestComponent) { if (recipeComponent.IsTransformationInput) { for (var i = requestComponent.Resolutions.Count - 1; i >= 0; i--) { if (requestComponent.Resolutions[i].BatchNumber ?.Equals(request.ProducingBatchNumber ?? string.Empty) != true) { requestComponent.Resolutions.RemoveAt(i); } } if (string.IsNullOrWhiteSpace(request.ProducingBatchNumber)) { requestComponent.Invalidate("Receptura vyžaduje shodné číslo šarže"); } return(true); } return(false); }
private void add(ProductionComponent prod) { prod_.Add(prod); }
private void remove(ProductionComponent prod) { prod_.Remove(prod); }
private void Date_TimeChanged(GameDateComponent sender) { long elapsed = World.Date.MinutesElapsed(lastUpdate); lastUpdate = World.Date.Time; List <Entity> producers = World.Entities.FindAll(delegate(Entity e) { return(e.HasComponent <ProductionComponent>()); }); foreach (Entity e in producers) { ProductionComponent p = e.Get <ProductionComponent>(); if (string.IsNullOrWhiteSpace(p.Recipe)) { continue; } // determines how much work is done // TODO: check for divide by zero? float workerPercentage = (float)p.Employees.Length / (float)p.MaxEmployees; p.WorkDone += (elapsed * workerPercentage); Recipe r = (Recipe)World.Prototypes[p.Recipe]; if (p.WorkDone >= r.Stages[p.CurrentStage].WorkRequired) { // TODO: check the inputs and modify or elminate the output based on the amount of inputs present // store output in the inventory Inventory inventory = e.Get <Inventory>(); RecipeStage stage = r.Stages[p.CurrentStage]; foreach (RecipeOutput output in stage.Outputs) { inventory.Add(output.Item, output.AmountProduced); // make sure the newly produced item is marked as output inventory.Items[output.Item].Output = true; } // go to next stage in the recipe p.CurrentStage++; if (p.CurrentStage >= r.Stages.Count) { p.CurrentStage = 0; } // reset the work done p.WorkDone = 0; // update the drawables DrawableComponent drawable = e.Get <DrawableComponent>(); stage = r.Stages[p.CurrentStage]; // remove foreach (string str in stage.RemoveFromDrawableComponent) { drawable.RemoveByPrototypeID(str); } // add foreach (string str in stage.AddToDrawableComponent) { GameDrawable igd = (GameDrawable)World.Prototypes[str]; drawable.Add(igd.Layer, igd); } } } }
private void ProcessResolutions(ProductionRequest request, IRecipeComponent recipeComponent, ProductionComponent requestComponent, decimal multiplier, DateTime sourceBatchesMadeBefore) { if (TryProcessTransformationInput(request, recipeComponent, requestComponent) && (!requestComponent.IsValid)) { return; } var requiredAmount = new Amount(recipeComponent.Amount * multiplier, m_unitRepository.GetUnit(recipeComponent.UnitId)); ClearUserAllocationsIfQuantityChanged(requestComponent, requiredAmount); var requiredBatchNr = recipeComponent.IsTransformationInput ? request.ProducingBatchNumber : null; var resolutions = m_batchFacade.ResolveMaterialDemand( recipeComponent.MaterialId, requiredAmount, requiredBatchNr, false, true, sourceBatchesMadeBefore, request.SourceSegmentId); RemoveComponentsNotProposedBySystem(requestComponent, resolutions, requiredAmount); AddMissingComponents(requestComponent, resolutions, requiredAmount, request.SourceSegmentId != null && request.IsFirstRound); var userAllocatedAmount = m_amountProcessor.Sum(requestComponent.Resolutions.Where(r => r.GetAmount(m_unitRepository) != null) .Select(r => r.GetAmount(m_unitRepository))) ?? new Amount(0, requiredAmount.Unit); var remaining = m_amountProcessor.Subtract(requiredAmount, userAllocatedAmount); if (!resolutions.CompletelyAllocated) { requestComponent.Invalidate("Potřebné množství není dostupné"); } if (remaining.IsPositive) { //seems we allocated the requested amount requestComponent.Invalidate($"Zbývá vložit {remaining}"); } else if (remaining.IsNegative) { requestComponent.Invalidate($"Přebývá {m_amountProcessor.Neg(remaining)}"); } }