public ErrorCodes PrototypeQuery(Character character, int targetDefinition, Prototyper prototyper, out Dictionary <string, object> replyDict)
        {
            var ec = ErrorCodes.NoError;

            replyDict = null;

            character.TechTreeNodeUnlocked(targetDefinition).ThrowIfFalse(ErrorCodes.TechTreeNodeNotFound);

            ProductionDescription productionDescription;

            if (!_productionDescriptions.TryGetValue(targetDefinition, out productionDescription))
            {
                Logger.Error("consistency error! no production description was found for: " + targetDefinition);
                return(ErrorCodes.ServerError);
            }

            var  facilityInfo         = prototyper.GetFacilityInfo(character);
            var  prototypeTimeSeconds = prototyper.CalculatePrototypeTimeSeconds(character, targetDefinition);
            var  price = prototyper.CalculatePrototypePrice(prototypeTimeSeconds);
            bool hasBonus;
            var  materialMultiplier  = prototyper.CalculateMaterialMultiplier(character, targetDefinition, out hasBonus);
            var  materials           = ProductionDescription.GetRequiredComponentsInfo(ProductionInProgressType.prototype, 1, materialMultiplier, productionDescription.Components.ToList());
            var  prototypeDefinition = _productionDataAccess.GetPrototypePair(targetDefinition);

            replyDict = new Dictionary <string, object>
            {
                { k.materials, materials },
                { k.price, price },
                { k.productionTime, prototypeTimeSeconds },
                { k.facility, facilityInfo },
                { k.targetDefinition, prototypeDefinition },
                { k.materialEfficiency, materialMultiplier },
                { k.hasBonus, hasBonus }
            };

            return(ec);
        }
        public IDictionary <string, object> PrototypeStart(Character character, int targetDefinition, Container container, Prototyper prototyper, bool useCorporationWallet)
        {
            var maxSlotCount           = prototyper.RealMaxSlotsPerCharacter(character);
            var facilityEid            = prototyper.Eid;
            var runningProductionCount = RunningProductions.GetRunningProductionsByFacilityAndCharacter(character, facilityEid).Count();

            runningProductionCount.ThrowIfGreater(maxSlotCount - 1, ErrorCodes.MaximumAmountOfProducionsReached);

            ProductionDescription productionDescription;

            _productionDescriptions.TryGetValue(targetDefinition, out productionDescription).ThrowIfFalse(ErrorCodes.ServerError);

            bool hasBonus;
            var  newProduction = prototyper.StartPrototype(character, productionDescription, container, useCorporationWallet, out hasBonus);

            //save to sql
            newProduction.InsertProductionInProgess();
            container.Save();

            //add to ram
            Transaction.Current.OnCommited(() => AddToRunningProductions(newProduction));

            newProduction.SendProductionEventToCorporationMembersOnCommitted(Commands.ProductionRemoteStart);

            //return info
            var replyDict = new Dictionary <string, object>();

            var productionDict = newProduction.ToDictionary();

            replyDict.Add(k.production, productionDict);

            var facilityInfo = prototyper.GetFacilityInfo(character);

            replyDict.Add(k.facility, facilityInfo);

            var containerData = container.ToDictionary();

            replyDict.Add(k.sourceContainer, containerData);

            replyDict.Add(k.hasBonus, hasBonus);

            return(replyDict);
        }