Example #1
0
        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;
                }
            }
        }
Example #2
0
        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));
            }
        }
Example #3
0
 private static void ClearUserAllocationsIfQuantityChanged(ProductionComponent requestComponent, Amount requiredAmount)
 {
     if (!requiredAmount.ToString().Equals(requestComponent.LastClientAmount ?? string.Empty))
     {
         requestComponent.Resolutions.Clear();
         requestComponent.LastClientAmount = requiredAmount.ToString();
     }
 }
Example #4
0
        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();
            }
        }
Example #5
0
        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)));
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
 private void add(ProductionComponent prod)
 {
     prod_.Add(prod);
 }
Example #10
0
 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);
                    }
                }
            }
        }
Example #12
0
        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)}");
            }
        }