/** * Research TE on this BLueprint. * * @param IndustryModifier $iMod the object that holds all the information about skills, implants, system industry * indices, tax and assemblyLines * @param int $startTE the initial TE level * @param int $endTE the TE level after the research * @param int $manuRecursionDepth defines if and how deep used materials should be manufactured recursively * * @return \iveeCore\ResearchTEProcessData describing the research process */ public function researchTE(IndustryModifier $iMod, $startTE, $endTE, $manuRecursionDepth = 1) { $startTE = abs((int) $startTE); $endTE = abs((int) $endTE); if ($startTE < 0 or $startTE >= $endTE or $endTE > 20 or $startTE % 2 != 0 or $endTE % 2 != 0) { self::throwException('InvalidParameterValueException', "Invalid start or end research levels given"); } //get modifiers and test if TE research is possible with the given assemblyLines $modifier = $iMod->getModifier(ProcessData::ACTIVITY_RESEARCH_TE, $this); $scaleModifier = static::calcResearchMultiplier($startTE / 2, $endTE / 2); $researchTEDataClass = Config::getIveeClassName('ResearchTEProcessData'); $rtdata = new $researchTEDataClass($this->id, ceil($scaleModifier * $modifier['t'] * $this->getBaseTimeForActivity(ProcessData::ACTIVITY_RESEARCH_TE)), $scaleModifier * $modifier['c'] * $this->getProductBaseCost($iMod->getMaxPriceDataAge()) * 0.02, -$startTE, -$endTE, $modifier['solarSystemId'], $modifier['assemblyLineTypeId']); $rtdata->addSkillMap($this->getSkillMapForActivity(ProcessData::ACTIVITY_RESEARCH_TE)); $this->addActivityMaterials($iMod, $rtdata, ProcessData::ACTIVITY_RESEARCH_TE, $modifier['m'], ($endTE - $startTE) / 2, $manuRecursionDepth, 0); return $rtdata; }
/** * Returns an InventionProcessData object describing the invention process. * * @param \iveeCore\IndustryModifier $iMod the object with all the necessary industry modifying entities * @param int $inventedBpId the ID if the blueprint to be invented. If left null, it is set to the first * inventable blueprint ID * @param int $decryptorId the decryptor the be used, if any * @param int $manuRecursionDepth defines if and how deep used materials should be manufactured recursively * * @return \iveeCore\InventionProcessData * @throws \iveeCore\Exceptions\NotInventableException if the specified blueprint can't be invented from this * @throws \iveeCore\Exceptions\WrongTypeException if decryptorId isn't a decryptor */ public function invent(IndustryModifier $iMod, $inventedBpId = null, $decryptorId = null, $manuRecursionDepth = 1) { $inventionDataClass = Config::getIveeClassName('InventionProcessData'); $inventableBpIds = $this->getInventableBlueprintIds(); //if no inventedBpId given, set to first inventable BP ID if (is_null($inventedBpId)) { $inventedBpId = $inventableBpIds[0]; } elseif (!isset($this->inventsBlueprintIds[$inventedBpId])) { self::throwException('NotInventableException', "Specified blueprint can't be invented from this inventor blueprint."); } //get invented BP $inventedBp = Type::getById($inventedBpId); //get modifiers and test if inventing is possible with the given assemblyLines $modifier = $iMod->getModifier(ProcessData::ACTIVITY_INVENTING, $inventedBp->getProduct()); //calculate base cost, its the average of all possible invented BP's product base cost $baseCost = 0; $numInventableBps = 0; foreach ($inventableBpIds as $inventableBpId) { $inventableBp = Type::getById($inventableBpId); if ($inventableBp instanceof InventableBlueprint) { $baseCost += $inventableBp->getProductBaseCost($iMod->getMaxPriceDataAge()); $numInventableBps++; } } $baseCost = $baseCost / $numInventableBps; //with decryptor if ($decryptorId > 0) { $decryptor = $this->getAndCheckDecryptor($decryptorId); $idata = new $inventionDataClass($inventedBpId, $this->getBaseTimeForActivity(ProcessData::ACTIVITY_INVENTING) * $modifier['t'], $baseCost * 0.02 * $modifier['c'], $this->calcInventionProbability($iMod->getCharacterModifier()) * $decryptor->getProbabilityModifier(), $this->inventionOutputRuns + $decryptor->getRunModifier(), -2 - $decryptor->getMEModifier(), -4 - $decryptor->getTEModifier(), $modifier['solarSystemId'], $modifier['assemblyLineTypeId']); $idata->addMaterial($decryptorId, 1); } else { //without decryptor $idata = new $inventionDataClass($inventedBpId, $this->getBaseTimeForActivity(ProcessData::ACTIVITY_INVENTING) * $modifier['t'], $baseCost * 0.02 * $modifier['c'], $this->calcInventionProbability($iMod->getCharacterModifier()), $this->inventionOutputRuns, -2, -4, $modifier['solarSystemId'], $modifier['assemblyLineTypeId']); } $idata->addSkillMap($this->getSkillMapForActivity(ProcessData::ACTIVITY_INVENTING)); $this->addActivityMaterials($iMod, $idata, ProcessData::ACTIVITY_INVENTING, $modifier['m'], 1, $manuRecursionDepth, 0); return $idata; }
/** * Returns an InventionProcessData object describing the invention process. * * @param IndustryModifier $iMod the object with all the necessary industry modifying entities * @param int $inventedBpID the ID if the blueprint to be invented. If left null, it is set to the first * inventable blueprint ID * @param int $decryptorID the decryptor the be used, if any * @param boolean $recursive defines if manufacturables should be build recursively * * @return \iveeCore\InventionProcessData * @throws \iveeCore\Exceptions\NotInventableException if the specified blueprint can't be invented from this * @throws \iveeCore\Exceptions\WrongTypeException if decryptorID isn't a decryptor * @throws \iveeCore\Exceptions\InvalidDecryptorGroupException if a non-matching decryptor is specified */ public function invent(IndustryModifier $iMod, $inventedBpID = null, $decryptorID = null, $recursive = true) { $inventionDataClass = Config::getIveeClassName('InventionProcessData'); $typeClass = Config::getIveeClassName('Type'); $inventableBpIDs = $this->getInventableBlueprintIDs(); //if no inventedBpID given, set to first inventable BP ID if (is_null($inventedBpID)) { $inventedBpID = $inventableBpIDs[0]; } elseif (!isset($this->inventsBlueprintIDs[$inventedBpID])) { self::throwException('NotInventableException', "Specified blueprint can't be invented from this inventor blueprint."); } //get invented BP $inventedBp = $typeClass::getById($inventedBpID); //get modifiers and test if inventing is possible with the given assemblyLines $modifier = $iMod->getModifier(ProcessData::ACTIVITY_INVENTING, $inventedBp->getProduct()); //calculate base cost, its the average of all possible invented BP's product base cost $baseCost = 0; foreach ($inventableBpIDs as $inventableBpID) { $baseCost += $typeClass::getById($inventableBpID)->getProductBaseCost(); } $baseCost = $baseCost / count($inventableBpIDs); //with decryptor if ($decryptorID > 0) { $decryptor = $this->getAndCheckDecryptor($decryptorID); $idata = new $inventionDataClass($inventedBpID, $this->getBaseTimeForActivity(ProcessData::ACTIVITY_INVENTING) * $modifier['t'], $baseCost * 0.02 * $modifier['c'], $this->calcInventionProbability() * $decryptor->getProbabilityModifier(), $inventedBp->getMaxProductionLimit() + $decryptor->getRunModifier(), -2 - $decryptor->getMEModifier(), -4 - $decryptor->getTEModifier(), $modifier['solarSystemID'], $modifier['assemblyLineTypeID'], isset($modifier['teamID']) ? $modifier['teamID'] : null); $idata->addMaterial($decryptorID, 1); } else { //without decryptor $idata = new $inventionDataClass($inventedBpID, $this->getBaseTimeForActivity(ProcessData::ACTIVITY_INVENTING) * $modifier['t'], $baseCost * 0.02 * $modifier['c'], $this->calcInventionProbability(), $inventedBp->getMaxProductionLimit(), -2, -4, $modifier['solarSystemID'], $modifier['assemblyLineTypeID'], isset($modifier['teamID']) ? $modifier['teamID'] : null); } $idata->addSkillMap($this->getSkillMapForActivity(ProcessData::ACTIVITY_INVENTING)); $this->addActivityMaterials($iMod, $idata, ProcessData::ACTIVITY_INVENTING, $modifier['m'], 1, $recursive); return $idata; }
/** * Returns an ReverseEngineerProcessData object describing the reverse engineering process. It can give both * requirements per attempt or average per success, by using the appropriate methods. * * Note that, unlike with invention, it is not possible to select which item exactly is gonna be produced by the * reverse engineering process apart from the race. Therefore using this method for determining the profits for * a certain reverse engineered item is not realistic, as it does not take into account the other items that might * also be produced instead. The method reverseEngineerByRaceID() tries to better model this by calculating the * process for each of the possible results. * * @param IndustryModifier $iMod the object with all the necessary industry modifying entities * @param int $reverseEngineeredBpID the ID of the blueprint to be reverse engineered * @param boolean $recursive defines if manufacturables should be built recursively * * @return \iveeCore\ReverseEngineerProcessData * @throws \iveeCore\Exceptions\NotReverseEngineerableException if the specified blueprint can't be reverse * engineered from this Relic */ public function reverseEngineer(IndustryModifier $iMod, $reverseEngineeredBpID, $recursive = true) { $reverseEngineeringDataClass = Config::getIveeClassName('ReverseEngineerProcessData'); $typeClass = Config::getIveeClassName('Type'); if (!isset($this->reverseEngineersBlueprintIDs[$reverseEngineeredBpID])) { self::throwException('NotReverseEngineerableException', "Specified type can't be reverse engineered from this Relic"); } //get reverse engineered BP $reBP = $typeClass::getById($reverseEngineeredBpID); $decryptor = $reBP->getReverseEngineeringDecryptor(); //get modifiers and test if reverse engineering is possible with the given assemblyLines $modifier = $iMod->getModifier(ProcessData::ACTIVITY_REVERSE_ENGINEERING, $this); //calculate base cost, its the average of all possible reverse engineered BP's product base cost, which is the //same for all possible result REBlueprints, so we can just get it from the one we are RE'ing $baseCost = $reBP->getProductBaseCost(); $red = new $reverseEngineeringDataClass($reBP->getId(), $this->getBaseTimeForActivity(ProcessData::ACTIVITY_REVERSE_ENGINEERING) * $modifier['t'], $baseCost * 0.02 * $modifier['c'], $this->calcReverseEngineeringProbability() * $decryptor->getProbabilityModifier(), $this->getReverseEngineeringOutputRuns() + $decryptor->getRunModifier(), $modifier['solarSystemID'], $modifier['assemblyLineTypeID'], isset($modifier['teamID']) ? $modifier['teamID'] : null); $red->addMaterial($decryptor->getId(), 1); $red->addSkillMap($this->getSkillMapForActivity(ProcessData::ACTIVITY_REVERSE_ENGINEERING)); foreach ($this->getMaterialsForActivity(ProcessData::ACTIVITY_REVERSE_ENGINEERING) as $matID => $matData) { $mat = $typeClass::getById($matID); //calculate total quantity needed, applying all modifiers $totalNeeded = ceil($matData['q'] * $modifier['m']); //if consume flag is set to 0, add to needed mats with quantity 0 if (isset($matData['c']) and $matData['c'] == 0) { $red->addMaterial($matID, 0); continue; } //if using recursive building and material is manufacturable, recurse! if ($recursive and $mat instanceof Manufacturable) { $red->addSubProcessData($mat->getBlueprint()->manufacture($iMod, $totalNeeded)); } else { $red->addMaterial($matID, $totalNeeded); } } return $red; }
/** * Returns material sell value, considering specific taxes. The best station (lowest tax) in system will be * chosen for that unless another preferred station is set on the IndustryModifier object. * Items that are not on the market will be ignored. * * @param \iveeCore\IndustryModifier $sellContext for market context * * @return float * @throws \iveeCore\Exceptions\PriceDataTooOldException if $maxPriceDataAge is exceeded by any of the materials */ public function getMaterialSellValue(IndustryModifier $sellContext) { $sum = 0; foreach ($this->getMaterials() as $typeId => $amount) { $type = Type::getById($typeId); if (!$type->onMarket()) { continue; } if ($amount > 0) { $sum += $type->getMarketPrices($sellContext->getSolarSystem()->getRegionId(), $sellContext->getMaxPriceDataAge())->getSellPrice($sellContext->getMaxPriceDataAge()) * $amount * $sellContext->getSellTaxFactor(); } } return $sum; }