//Overload method for price/sec public virtual double GetPricePerSecond(int targetDefinition) { var mod = Math.Max(1, ProductionDataAccess.GetProductionPriceModifier(targetDefinition)); mod = Math.Min(10, mod); return(GetPricePerSecond() * mod); }
private void DealWithCPRGGenerators(MissionInProgress missionInProgress) { var source = GetSourceTargetForPrimaryAndSolve(missionInProgress); if (source != null) { //linked to a target which creates a CPRG artificially. //item supply or spawn item currently if (!source.myTarget.ValidDefinitionSet) { Logger.Error("no cprg definition is set in: " + source); throw new PerpetuumException(ErrorCodes.ConsistencyError); } if (source.myTarget.PrimaryEntityDefault.CategoryFlags.IsCategory(CategoryFlags.cf_random_calibration_programs)) { Log("linked to a CPRG generator. " + source); //this is the item the CPRG will aid to massproduce var targetDefinition = ProductionDataAccess.GetResultingDefinitionFromCalibrationDefinition(source.myTarget.Definition); definition = targetDefinition; if (!ValidQuantitySet) { quantity = 1; //start scaling :) } Log("definition is set to CPRG result: " + source.myTarget.Definition + " -> " + targetDefinition); } } }
private double CalculateFinalMaterialMultiplier(Character character, int lineOrCPRGMaterialPoints, int definition, out bool hasBonus) { hasBonus = character.HasTechTreeBonus(ProductionDataAccess.GetOriginalDefinitionFromPrototype(definition)); var millBonus = hasBonus ? HasMillBonus : NoMillBonus; var multiplier = 1 + (50.0 / (lineOrCPRGMaterialPoints + GetAdditiveComponentForMaterial(character) + 100.0 + millBonus)); return(multiplier); }
/// <summary> /// Sets the definition as one of the source items of a research - the item to researh /// </summary> /// <param name="missionInProgress"></param> /// <param name="usePrimaryLink"></param> protected bool TryGetResearchableItemFromResearchTarget(MissionInProgress missionInProgress, bool usePrimaryLink = true) { MissionTargetInProgress linkedTarget; if (usePrimaryLink) { if (!ValidPrimaryLinkSet) { return(false); } linkedTarget = GetSourceTargetForPrimaryAndSolve(missionInProgress); } else { if (!ValidSecondaryLinkSet) { return(false); } linkedTarget = GetSourceTargetForSecondaryAndSolve(missionInProgress); } if (linkedTarget?.TargetType == MissionTargetType.research) { if (!linkedTarget.myTarget.ValidDefinitionSet) { Logger.Error("no valid cprg definition is set for " + linkedTarget.myTarget); throw new PerpetuumException(ErrorCodes.ConsistencyError); } //this target is created to aid the research. It must spawn an original item //and there must be a way to get the decoder as well along the mission //cannot use selected definition exceptions var itemDefinition = ProductionDataAccess.GetResultingDefinitionFromCalibrationDefinition(linkedTarget.myTarget.Definition); missionInProgress.AddToSelectedItems(itemDefinition); //as a side effect it may happen that previous targets choose this definition. dont be surprised! //possible workaround // position the spawn targets as the last/first items, so they will find the item amongst the choosen ones // according to research targets in mission definition = itemDefinition; quantity = 1; Log("researchable item resolved:" + PrimaryEntityDefault.Name + " from " + linkedTarget.myTarget); return(true); } return(false); }
public double CalculateMaterialMultiplier(Character character, int targetDefinition, out bool hasBonus) { //(1+(50/(PC_EXT_PONT+PROTOTYPER.ME_PONT +100)))*10*targetDefintion.basematerial hasBonus = character.HasTechTreeBonus(ProductionDataAccess.GetOriginalDefinitionFromPrototype(targetDefinition)); var itemLevel = hasBonus ? HasPrototyperBonus : NoPrototyperBonus; var multiplier = (1 + (50 / (GetAdditiveComponentForMaterial(character) + 100.0))) * itemLevel; return(multiplier); }
public Dictionary <string, object> QueryMaterialAndTime(CalibrationProgram calibrationProgram, Character character, int targetDefintion, int lineOrCPRGMaterialPoints, int lineOrCPRGTimePoints, bool forNextRound = false) { var result = new Dictionary <string, object>(); if (forNextRound) { var decalibration = ProductionDataAccess.GetDecalibration(targetDefintion); double newMaterialEfficiency = 0; double newTimeEfficiency = 0; ProductionLine.GetDecalibratedEfficiencies(lineOrCPRGMaterialPoints, lineOrCPRGTimePoints, decalibration.decrease, ref newMaterialEfficiency, ref newTimeEfficiency); lineOrCPRGMaterialPoints = (int)newMaterialEfficiency; lineOrCPRGTimePoints = (int)newTimeEfficiency; } bool hasBonus; var materialMultiplier = CalculateFinalMaterialMultiplier(character, lineOrCPRGMaterialPoints, targetDefintion, out hasBonus); if (calibrationProgram.IsMissionRelated) { materialMultiplier = materialMultiplier.Clamp(); //never ask more than what we have in the mission } var materials = ProductionDescription.GetRequiredComponentsInfo(ProductionInProgressType.massProduction, 1, materialMultiplier, calibrationProgram.Components); materials.Count.ThrowIfEqual(0, ErrorCodes.WTFErrorMedicalAttentionSuggested); var productionTimeSeconds = CalculateFinalProductionTimeSeconds(character, targetDefintion, lineOrCPRGTimePoints); var price = CalculateProductionPrice(productionTimeSeconds); if (calibrationProgram.IsMissionRelated) { //mission stuff is fixed price = 0; productionTimeSeconds = 10; } result.Add(k.materials, materials); result.Add(k.productionTime, productionTimeSeconds); result.Add(k.price, price); result.Add(k.definition, targetDefintion); result.Add(k.materialMultiplier, materialMultiplier); result.Add(k.hasBonus, hasBonus); result.Add(k.targetQuantity, calibrationProgram.TargetQuantity); return(result); }
public int CalculateFinalProductionTimeSeconds(Character character, int targetDefinition, int lineOrCPRGTimePoints) { if (EntityDefault.Get(targetDefinition).CategoryFlags.IsCategory(CategoryFlags.cf_random_items)) { return(10); //fix time for mission items } //definition related time modifier var durationModifier = ProductionDataAccess.GetProductionDuration(targetDefinition); var multiplier = CalculateFinalTimeMultiplier(character, targetDefinition, lineOrCPRGTimePoints); var facilityProductionTime = GetProductionTimeSeconds(); return((int)(facilityProductionTime * multiplier * durationModifier)); }
private int GetCalibrationProgramFromPool(MissionInProgress missionInProgress) { var possibleRandomCPRGList = EntityDefault.All.GetByCategoryFlags(CategoryFlags.cf_random_calibration_programs).Select(d => d.Definition).ToList(); Log("possible CPRG definitions:" + possibleRandomCPRGList.Count); var exceptCPRGDefinitions = missionInProgress.CollectCPRGDefinitionsFromItems(); possibleRandomCPRGList = possibleRandomCPRGList.Except(missionInProgress.SelectedItemDefinitions).Except(exceptCPRGDefinitions).ToList(); Log("except choosen:" + possibleRandomCPRGList.Count); if (possibleRandomCPRGList.Count == 0) { Log("no possible CPRG definitions to select from. " + this + " " + missionInProgress); throw new PerpetuumException(ErrorCodes.ConsistencyError); } //now we load the active cprg definitions from the character/gang var activeCPRGDefinitions = missionInProgress.CollectActiveCPRGDefinitions(); Log("active CPRG definitions:" + activeCPRGDefinitions.Count); possibleRandomCPRGList = possibleRandomCPRGList.Except(activeCPRGDefinitions).ToList(); Log("except active: " + possibleRandomCPRGList.Count); if (possibleRandomCPRGList.Count == 0) { Log("too many active cprgs running. mission resolve fails " + this + " " + missionInProgress); throw new PerpetuumException(ErrorCodes.TooManyActiveCPRG); } var choosenCPRG = possibleRandomCPRGList.RandomElement(); //exclude missionInProgress.AddToSelectedItems(choosenCPRG); //and exclude this as well var resultingDefinition = ProductionDataAccess.GetResultingDefinitionFromCalibrationDefinition(choosenCPRG); missionInProgress.AddToSelectedItems(resultingDefinition); Log("selected CPRG: " + EntityDefault.Get(choosenCPRG).Name + " " + choosenCPRG); return(choosenCPRG); }
public int CalculatePrototypeTimeSeconds(Character character, int targetDefinition) { //(1+(100/( PC_EXT_PONT+100))*10 *Prototyper.productionTime *targetDefinition.CF.durationMultiplier var durationModifier = ProductionDataAccess.GetProductionDuration(targetDefinition); var multiplier = 1 + (100 / (GetAdditiveComponentForTime(character) + 100.0)); var configPrototypeTime = GetProductionTimeSeconds(); var rawValue = multiplier * 10 * durationModifier * configPrototypeTime; if (rawValue > int.MaxValue) { Logger.Error("overflow in CalculatePrototypeTimeSeconds. definition:" + targetDefinition + " durationModifier:" + durationModifier + " multiplier:" + multiplier + " configPrototypeTime:" + configPrototypeTime + " characterID:" + character.Id); rawValue = int.MaxValue; } return((int)rawValue); }
public IDictionary <string, object> ResearchQuery(Character character, int researchKitDefinition, int targetDefinition) { var replyDict = new Dictionary <string, object> { { k.researchKitDefinition, researchKitDefinition }, { k.itemDefinition, targetDefinition } }; var researchKitDefault = EntityDefault.Get(researchKitDefinition); var itemDefault = EntityDefault.Get(targetDefinition); var missionRelated = false; //match item vs research kit vs mission if (researchKitDefault.CategoryFlags.IsCategory(CategoryFlags.cf_random_research_kits)) { itemDefault.CategoryFlags.IsCategory(CategoryFlags.cf_generic_random_items).ThrowIfFalse(ErrorCodes.OnlyMissionItemAccepted); missionRelated = true; } if (itemDefault.CategoryFlags.IsCategory(CategoryFlags.cf_generic_random_items)) { researchKitDefault.CategoryFlags.IsCategory(CategoryFlags.cf_random_research_kits).ThrowIfFalse(ErrorCodes.OnlyMissionResearchKitAccepted); missionRelated = true; } //on gamma not even possible if (GetDockingBase().IsOnGammaZone()) { missionRelated.ThrowIfTrue(ErrorCodes.MissionItemCantBeResearchedOnGamma); } var researchKitLevel = ResearchKit.GetResearchLevelByDefinition(researchKitDefinition); replyDict.Add(k.researchKitLevel, researchKitLevel); var isPrototypeItem = ProductionDataAccess.IsPrototypeDefinition(targetDefinition); Logger.Info("item definition: " + EntityDefault.Get(targetDefinition).Name + " isPrototype:" + isPrototypeItem); var nominalDict = new Dictionary <string, object>(); var realDict = new Dictionary <string, object>(); //match research levels var itemLevel = ProductionDataAccess.GetResearchLevel(targetDefinition); itemLevel.ThrowIfEqual(0, ErrorCodes.ItemNotResearchable); itemLevel.ThrowIfGreater(researchKitLevel, ErrorCodes.ResearchLevelMismatch); var itemResearchLevel = ProductionDataAccess.ResearchLevels.GetOrDefault(targetDefinition).ThrowIfNull(ErrorCodes.ItemNotResearchable); var outputDefinition = (int)itemResearchLevel.calibrationProgramDefinition.ThrowIfNull(ErrorCodes.ServerError); //calculate CalculateFinalResearchTimeSeconds(character, itemLevel, researchKitLevel, isPrototypeItem, out int researchTimeSeconds, out int levelDifferenceBonusPoints); researchTimeSeconds = GetShortenedProductionTime(researchTimeSeconds); var price = missionRelated ? 0.0 : researchTimeSeconds *GetPricePerSecond(targetDefinition); ProductionDataAccess.GetCalibrationDefault(outputDefinition, out int materialEfficiency, out int timeEfficiency); var rawMaterialEfficiency = materialEfficiency; CalculateMaterialAndTimeEfficiency(character, itemResearchLevel, levelDifferenceBonusPoints, ref materialEfficiency, ref timeEfficiency); if (missionRelated) { //the material efficiency must be default 1.0 materialEfficiency = rawMaterialEfficiency; } //calculate nominal var nominalResearchTimeSeconds = CalculateNominalResearchTimeSeconds(character, itemResearchLevel.researchLevel); var nominalPrice = missionRelated ? 0.0 : nominalResearchTimeSeconds *GetPricePerSecond(targetDefinition); ProductionDataAccess.GetCalibrationDefault(outputDefinition, out int nominalMaterialEfficiency, out int nominalTimeEfficiency); var rawNominalMatEff = nominalMaterialEfficiency; CalculateMaterialAndTimeEfficiency(character, itemResearchLevel, 0, ref nominalMaterialEfficiency, ref nominalTimeEfficiency); if (missionRelated) { nominalMaterialEfficiency = rawNominalMatEff; researchTimeSeconds = 10; nominalResearchTimeSeconds = 10; } //collect definition related replyDict.Add(k.calibrationProgram, itemResearchLevel.calibrationProgramDefinition); //collect real realDict.Add(k.price, (long)price); realDict.Add(k.researchTime, researchTimeSeconds); realDict.Add(k.materialEfficiency, materialEfficiency); realDict.Add(k.timeEfficiency, timeEfficiency); //collect nominal nominalDict.Add(k.price, (long)nominalPrice); nominalDict.Add(k.researchTime, nominalResearchTimeSeconds); nominalDict.Add(k.materialEfficiency, nominalMaterialEfficiency); nominalDict.Add(k.timeEfficiency, nominalTimeEfficiency); replyDict.Add(k.real, realDict); replyDict.Add(k.nominal, nominalDict); replyDict.Add(k.facility, Eid); return(replyDict); }
private IDictionary <string, object> EndResearch(ProductionInProgress productionInProgress) { Logger.Info("research finished: " + productionInProgress); Item item; ResearchKit researchKit; LoadItemAndResearchKit(productionInProgress, out researchKit, out item).ThrowIfError(); var isPrototypeItem = ProductionDataAccess.IsPrototypeDefinition(item.Definition); var itemLevel = ProductionDataAccess.GetResearchLevel(item.Definition); var researchKitLevel = researchKit.GetResearchLevel(); int researchTime; int levelDifferenceBonusPoints; CalculateFinalResearchTimeSeconds(productionInProgress.character, itemLevel, researchKitLevel, isPrototypeItem, out researchTime, out levelDifferenceBonusPoints); var outputDefinition = productionInProgress.resultDefinition; //load public container var targetContainer = (PublicContainer)Container.GetOrThrow(PublicContainerEid); targetContainer.ReloadItems(productionInProgress.character); var outputDefault = EntityDefault.Get(outputDefinition).ThrowIfEqual(EntityDefault.None, ErrorCodes.DefinitionNotSupported); (outputDefault.CategoryFlags.IsCategory(CategoryFlags.cf_calibration_programs) || outputDefault.CategoryFlags.IsCategory(CategoryFlags.cf_random_calibration_programs)).ThrowIfFalse(ErrorCodes.WTFErrorMedicalAttentionSuggested); //create item var resultItem = targetContainer.CreateAndAddItem(outputDefinition, false, item1 => { item1.Owner = productionInProgress.character.Eid; item1.Quantity = 1; }); var calibrationProgram = resultItem as CalibrationProgram; calibrationProgram.ThrowIfNull(ErrorCodes.ConsistencyError); var itemResearchLevel = ProductionDataAccess.GetItemReserchLevelByCalibrationProgram(calibrationProgram); int materialEfficiency; int timeEfficiency; researchKit.GetCalibrationDefaults(outputDefault, out materialEfficiency, out timeEfficiency); var rawMatEff = materialEfficiency; //modify the results even further CalculateMaterialAndTimeEfficiency(productionInProgress.character, itemResearchLevel, levelDifferenceBonusPoints, ref materialEfficiency, ref timeEfficiency); if (calibrationProgram.IsMissionRelated) { materialEfficiency = rawMatEff; calibrationProgram.MaterialEfficiencyPoints = rawMatEff; calibrationProgram.TimeEfficiencyPoints = timeEfficiency; } else { calibrationProgram.MaterialEfficiencyPoints = materialEfficiency; calibrationProgram.TimeEfficiencyPoints = timeEfficiency; } var randomCalibrationProgram = calibrationProgram as RandomCalibrationProgram; //for random missions look up for targets, gang and stuff randomCalibrationProgram?.SetComponentsFromRunningTargets(productionInProgress.character); calibrationProgram.Save(); productionInProgress.character.WriteItemTransactionLog(TransactionType.ResearchCreated, calibrationProgram); //delete the used items Repository.Delete(item); Repository.Delete(researchKit); productionInProgress.character.WriteItemTransactionLog(TransactionType.ResearchDeleted, item); productionInProgress.character.WriteItemTransactionLog(TransactionType.ResearchDeleted, researchKit); targetContainer.Save(); Logger.Info("endResearch created an item: " + calibrationProgram + " production:" + productionInProgress); var replyDict = new Dictionary <string, object> { { k.result, calibrationProgram.ToDictionary() } }; ProductionProcessor.EnqueueProductionMissionTarget(MissionTargetType.research, productionInProgress.character, MyMissionLocationId(), calibrationProgram.Definition); return(replyDict); }
/// <summary> /// Generate the item's definition the ct will create /// </summary> private void GenerateResearchResultAsSecondaryDefinition(MissionInProgress missionInProgress) { //the default item related to the CT secondaryDefinition = ProductionDataAccess.GetResultingDefinitionFromCalibrationDefinition(Definition); Log("Default definition is used for the CPRG"); }