diff --git a/includes/application/code/community/Legacies.php b/includes/application/code/community/Legacies.php index 473b39f..87a36f4 100644 --- a/includes/application/code/community/Legacies.php +++ b/includes/application/code/community/Legacies.php @@ -9,6 +9,8 @@ class Legacies public static $request = null; public static $response = null; + protected static $_now = null; + public static function registerListener($event, $listener) { if (!isset(self::$_listeners[$event])) { @@ -72,4 +74,12 @@ class Legacies { return 'fr_FR'; } + + public static function now() + { + if (self::$_now === null) { + self::$_now = time(); + } + return self::$_now; + } } \ No newline at end of file diff --git a/includes/application/code/community/Legacies/Empire/Model/BuilderAbstract.php b/includes/application/code/community/Legacies/Empire/Model/BuilderAbstract.php index 4f1214c..00262a9 100644 --- a/includes/application/code/community/Legacies/Empire/Model/BuilderAbstract.php +++ b/includes/application/code/community/Legacies/Empire/Model/BuilderAbstract.php @@ -42,8 +42,12 @@ abstract class Legacies_Empire_Model_BuilderAbstract { $this->_currentPlanet = $currentPlanet; $this->_currentUser = $currentUser; + + $this->init(); } + abstract public function init(); + abstract protected function _initItem(); public function enqueue() @@ -51,14 +55,14 @@ abstract class Legacies_Empire_Model_BuilderAbstract $params = func_get_args(); $item = call_user_func_array(array($this, '_initItem'), $params); $item->setIndex($this->_index); - $queue[$this->_index++] = $item; + $this->_queue[$this->_index++] = $item; return $this; } public function dequeue($itemIndex) { - unset($itemIndex); + unset($this->_queue[$itemIndex]); return $this; } @@ -84,12 +88,17 @@ abstract class Legacies_Empire_Model_BuilderAbstract protected function _unserializeQueue($serialized) { $this->clearQueue(); - $reflection = new ReflectionClass($this->_itemClass); $unserialized = unserialize($serialized); - foreach ($unserialized as $itemData) { - $this->_enqueue($reflection->newInstance($itemData)); + if ($unserialized === false) { + $this->_queue = array(); + return $this; } + + foreach ($unserialized as $itemData) { + call_user_func_array(array($this, 'enqueue'), $itemData); + } + return $this; } @@ -103,9 +112,6 @@ abstract class Legacies_Empire_Model_BuilderAbstract return $this->_queue; } - abstract public function enqueue($item); - abstract public function dequeue($item); - public function clearQueue() { $this->_queue = array(); @@ -158,4 +164,48 @@ abstract class Legacies_Empire_Model_BuilderAbstract abstract public function getResourcesNeeded($typeId, $level); abstract public function getBuildingTime($typeId, $level); + + public function serialize() + { + return $this->_serializeQueue(); + } + + public function unserialize($serialized) + { + $this->_unserializeQueue($serialized); + } + + public function count() + { + return count($this->_queue); + } + + public function current() + { + return current($this->_queue); + } + + public function next() + { + $element = next($this->_queue); + $this->_index = key($this->_queue); + + return $element; + } + + public function key() + { + return $this->_index; + } + + public function valid() + { + return $this->current() !== false; + } + + public function rewind() + { + reset($this->_queue); + $this->_index = 0; + } } \ No newline at end of file diff --git a/includes/application/code/community/Legacies/Empire/Model/Planet.php b/includes/application/code/community/Legacies/Empire/Model/Planet.php index bb59b8a..aa9ea68 100644 --- a/includes/application/code/community/Legacies/Empire/Model/Planet.php +++ b/includes/application/code/community/Legacies/Empire/Model/Planet.php @@ -15,7 +15,9 @@ class Legacies_Empire_Model_Planet protected $_user = null; protected $_moon = null; - protected $_now = null; + + protected $_builder = null; + protected $_shipyard = null; protected static $_instances = array(); @@ -48,17 +50,19 @@ class Legacies_Empire_Model_Planet public function _init() { - $this->_now = time(); $this->_tableName = 'planets'; $this->_idFieldName = 'id'; + + $this->_builder = new Legacies_Empire_Model_Planet_Builder($this, $this->getUser()); } - /** - * @deprecated - */ - protected function _now() + public function _afterLoad() { - return $this->_now; + parent::_afterLoad(); + + $this->_builder->init(); + + return $this; } public function getLastUpdate() @@ -73,22 +77,20 @@ class Legacies_Empire_Model_Planet public function updateStorages($time = null) { - Math::setPrecision(10); + Math::setPrecision(50); $resources = Legacies_Empire_Model_Game_Resources::getSingleton(); foreach ($resources->getAllDatas() as $resource => $resourceData) { if (!isset($resourceData['storage_field']) || $resourceData['storage_field'] === null && $this['rpg_stockeur'] === null) { continue; } - Math::setPrecision(1); - $officerEnhancement = Math::add(Math::mul(.5, $this->getData('rpg_stockeur'), 50), 1, 10, 50); + $officerEnhancement = (.5 * $this->getData('rpg_stockeur')) + 1; - Math::setPrecision(0); - $storageEnhancementFactor = Math::pow(1.6, $this[Legacies_Empire::getFieldName($resourceData['storage'])]); + $storageEnhancementFactor = Math::floor(Math::pow(1.6, $this[Legacies_Empire::getFieldName($resourceData['storage'])])); $storageEnhancement = Math::mul(BASE_STORAGE_SIZE / 2, $storageEnhancementFactor); $value = Math::mul(MAX_OVERFLOW, Math::mul($officerEnhancement, Math::add(BASE_STORAGE_SIZE, $storageEnhancement))); - $this->setData($resourceData['storage_field'], $value); + $this->setData($resourceData['storage_field'], Math::floor($value)); } Math::setPrecision(); @@ -102,7 +104,7 @@ class Legacies_Empire_Model_Planet $production = Legacies_Empire_Model_Game_Production::getSingleton(); if ($time === null) { - $time = $this->_now(); + $time = Legacies::now(); } if (!$this->isPlanet()) { @@ -207,11 +209,10 @@ class Legacies_Empire_Model_Planet $resources = Legacies_Empire_Model_Game_Resources::getSingleton(); if ($time === null) { - $time = $this->_now(); + $time = Legacies::now(); } $timeDiff = ($time - $this->getLastUpdate()) / 3600; - var_dump($time, $this->getLastUpdate(), $timeDiff); foreach ($resources->getAllDatas() as $resourceId => $resourceConfig) { $production = Math::mul($this->getData($resourceConfig['production_field']), $timeDiff); $this->setData($resourceConfig['field'], Math::min($production, $this->getData($resourceConfig['storage_field']))); @@ -244,6 +245,28 @@ class Legacies_Empire_Model_Planet return $this->_user; } + public function setUser(Legacies_Empire_Model_User $user) + { + $this->_user = $user; + + return $this; + } + + public function getShipyard() + { + if ($this->_shipyard === null) { + $this->_shipyard = new Legacies_Empire_Model_Planet_Building_Shipyard($this, $this->getUser()); + } + return $this->_shipyard; + } + + public function setShipyard(Legacies_Empire_Model_Planet_Building_Shipyard $shipyard) + { + $this->_shipyard = $shipyard; + + return $this; + } + public function isPlanet() { return (bool) ($this->getData('planet_type') == self::TYPE_PLANET); @@ -357,38 +380,44 @@ class Legacies_Empire_Model_Planet return $this->hasData($fields[$elementId]) && Math::comp($this->getElement($elementId), $levelRequired) > 0; } - public function appendQueue($buildingId) + public function appendQueue($buildingId, $time = null, $destroy = false) { $types = Legacies_Empire_Model_Game_Types::getSingleton(); + $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); if (!$types->is($buildingId, Legacies_Empire::TYPE_BUILDING)) { return $this; } - if (!$this->checkAvailability($buildingId)) { + if ($destroy === false && !$this->checkAvailability($buildingId)) { return $this; } - // Dispatch event + // Dispatch 'planet.building.append-queue.before' event Legacies::dispatchEvent('planet.building.append-queue.before', array( - 'ship_id' => $shipId, - 'qty' => $qty, - 'shipyard' => $this, - 'planet' => $this->_currentPlanet, - 'user' => $this->_currentUser + 'bulding_id' => $buildingId, + 'level' => $this->getElement($buildingId), + 'planet' => $this, + 'user' => $this->getUser(), + 'destroy' => $destroy )); + $this->_builder->enqueue($buildingId, $level, $time); + + //$elementBasePrice = $prices; + /* foreach ($this->_resourcesTypes as $resourceType) { $this->setData($resourceType, Math::sub($this->getData($resourceType), $resourcesNeeded[$resourceType])); } + */ - // Dispatch event + // Dispatch 'planet.shipyard.append-queue.after' event Legacies::dispatchEvent('planet.shipyard.append-queue.after', array( - 'ship_id' => $shipId, - 'qty' => $qty, - 'shipyard' => $this, - 'planet' => $this->_currentPlanet, - 'user' => $this->_currentUser + 'bulding_id' => $buildingId, + 'level' => $this->getElement($buildingId), + 'planet' => $this, + 'user' => $this->getUser(), + 'destroy' => $destroy )); return $this; @@ -551,6 +580,7 @@ class Legacies_Empire_Model_Planet } $user = $planet->getUser(); + /* if (($queue = $planet->getData('b_building_id')) != '0') { //FIXME: refactor buildings construciton list $explodedQueue = explode(';', $queue); foreach ($explodedQueue as $item) { @@ -558,9 +588,9 @@ class Legacies_Empire_Model_Planet if ($partialTime < $time) { $planet->updateResources($partialTime); - /*if (CheckPlanetBuildingQueue($planet, $user)) { + if (CheckPlanetBuildingQueue($planet, $user)) { SetNextQueueElementOnTop($planet, $user); - }*/ + } } else { $planet->updateResources($time); break; @@ -568,7 +598,9 @@ class Legacies_Empire_Model_Planet } } else { $planet->updateResources($time); - } + }*/ + $planet->updateResources($time); + $planet->getShipyard()->updateQueue($time); $planet->setLastUpdate($time); } } diff --git a/includes/application/code/community/Legacies/Empire/Model/Planet/Builder.php b/includes/application/code/community/Legacies/Empire/Model/Planet/Builder.php new file mode 100644 index 0000000..4da968b --- /dev/null +++ b/includes/application/code/community/Legacies/Empire/Model/Planet/Builder.php @@ -0,0 +1,39 @@ +_unserializeQueue($this->_currentPlanet->getData('b_building_id')); + } + + /** + * @param int $buildingId + * @param int $level + * @param int $time + */ + public function _initItem() + { + $buildingId = func_get_arg(0); + $level = func_get_arg(1); + $time = func_get_arg(2); + + return new Legacies_Empire_Model_Planet_Building_Shipyard_Item(array( + 'building_id' => $buildingId, + 'level' => $level, + 'created_at' => $time, + 'updated_at' => $time + )); + } + + public function getResourcesNeeded($typeId, $level) + { + return array(); + } + + public function getBuildingTime($typeId, $level) + { + return 0; + } +} \ No newline at end of file diff --git a/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard.php b/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard.php index 9438f0f..f1afa51 100644 --- a/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard.php +++ b/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard.php @@ -56,15 +56,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard * construction queue * @var array */ - protected $_queue = null; - - /** - * Current timestamp - * - * @var int - * @deprecated - */ - private $_now = 0; + protected $_builder = null; /** * Resource list @@ -117,9 +109,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard $this->_currentPlanet = $currentPlanet; $this->_currentUser = $currentUser; - $this->_queue = new Legacies_Empire_Model_Planet_Building_Shipyard_Builder($currentPlanet, $currentUser); - - $this->_now = time(); + $this->_builder = new Legacies_Empire_Model_Planet_Building_Shipyard_Builder($currentPlanet, $currentUser); } /** @@ -130,7 +120,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard */ protected function _now() { - return $this->_now; + return Legacies::now(); } /** @@ -154,7 +144,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard { $types = Legacies_Empire_Model_Game_Types::getSingleton(); - if (Math::comp($qty, 0) <= 0) { + if (Math::isPositive($qty)) { return $this; } @@ -181,10 +171,10 @@ class Legacies_Empire_Model_Planet_Building_Shipyard 'user' => $this->_currentUser )); - $resourcesNeeded = $this->_getResourcesNeeded($shipId, $qty); + $resourcesNeeded = $this->getResourcesNeeded($shipId, $qty); $buildTime = $this->getBuildTime($shipId, $qty); - $this->_queue->enqueue($shipId, $qty); + $this->_queue->enqueue($shipId, $qty, now()); foreach ($this->_resourcesTypes as $resourceType) { $this->_currentPlanet[$resourceType] = Math::sub($this->_currentPlanet[$resourceType], $resourcesNeeded[$resourceType]); @@ -209,48 +199,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard */ public function updateQueue($time = null) { - $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); - - if ($time === null) { - $time = $this->_now(); - } - $elapsedTime = $time - $this->_currentPlanet['b_hangar']; - - // Dispatch event - Legacies::dispatchEvent('planet.shipyard.update-queue.before', array( - 'shipyard' => $this, - 'planet' => $this->_currentPlanet, - 'user' => $this->_currentUser - )); - - foreach ($this->_queue as $id => &$element) { - $shipId = $element->getData('ship_id'); - $qty = $element->getData('qty'); - $buildTime = $this->getBuildTime($shipId, $qty); - - if ($elapsedTime >= $buildTime) { - $this->_currentPlanet[$fields[$shipId]] = Math::add($this->_currentPlanet[$fields[$shipId]], $qty); - $elapsedTime -= $buildTime; - unset($this->_queue[$id]); - continue; - } - - $timeRatio = $elapsedTime / $buildTime; - $itemsBuilt = Math::mul($timeRatio, $qty); - - $element->setData('updated_at', $time); - $element->setData('qty', Math::sub($qty, $itemsBuilt)); - $this->_currentPlanet->setData($fields[$shipId], Math::add($this->_currentPlanet->getData($fields[$shipId]), $itemsBuilt)); - break; - } - unset($element); - - // Dispatch event - Legacies::dispatchEvent('planet.shipyard.update-queue.after', array( - 'shipyard' => $this, - 'planet' => $this->_currentPlanet, - 'user' => $this->_currentUser - )); + $this->_builder->updateQueue($time); return $this; } @@ -275,39 +224,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard */ public function checkAvailability($shipId) { - $types = Legacies_Empire_Model_Game_Types::getSingleton(); - $requirements = Legacies_Empire_Model_Game_Requirements::getSingleton(); - - if (!isset($requirements[$shipId]) || empty($requirements[$shipId])) { - return true; - } - - foreach ($requirements[$shipId] as $requirement => $level) { - if ($types->is($requirement, Legacies_Empire::TYPE_BUILDING) && $this->_currentPlanet->hasElement($requirement, $level)) { - continue; - } else if ($types->is($requirement, Legacies_Empire::TYPE_RESEARCH) && $this->_currentUser->hasElement($requirement, $level)) { - continue; - } else if ($types->is($requirement, Legacies_Empire::TYPE_DEFENSE) && $this->_currentPlanet->hasElement($requirement, $level)) { - continue; - } else if ($types->is($requirement, Legacies_Empire::TYPE_SHIP) && $this->_currentPlanet->hasElement($requirement, $level)) { - continue; - } - return false; - } - - try { - // Dispatch event. Throw an exception to break the avaliability. - Legacies::dispatchEvent('planet.shipyard.check-availability', array( - 'ship_id' => $shipId, - 'shipyard' => $this, - 'planet' => $this->_currentPlanet, - 'user' => $this->_currentUser - )); - } catch (Exception $e) { - return false; - } - - return true; + return $this->_builder->checkAvailability($shipId); } /** @@ -320,13 +237,7 @@ class Legacies_Empire_Model_Planet_Building_Shipyard */ protected function _checkMaximumQuantity($shipId, $qty) { - $max = $this->getMaximumBuildableElementsCount($shipId); - - if (Math::comp($qty, $max) > 0) { - return $max; - } - - return $qty; + return Math::min($qty, $this->getMaximumBuildableElementsCount($shipId)); } /** @@ -338,122 +249,17 @@ class Legacies_Empire_Model_Planet_Building_Shipyard */ public function getMaximumBuildableElementsCount($shipId) { - $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); - $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); - - $resources = array( - Legacies_Empire::RESOURCE_METAL, - Legacies_Empire::RESOURCE_CRISTAL, - Legacies_Empire::RESOURCE_DEUTERIUM, - Legacies_Empire::RESOURCE_ENERGY - ); - - $qty = 0; - foreach ($resources as $resourceId) { - if (isset($prices[$shipId]) && isset($prices[$shipId][$resourceId]) && Math::comp($prices[$shipId][$resourceId], 0) > 0) { - $maxQty = Math::floor(Math::div($this->_currentPlanet->getData($resourceId), $prices[$shipId][$resourceId])); - - if ($maxQty == 0) { - return 0; - } - - if ($qty == 0 || Math::comp($maxQty, $qty) < 0) { - $qty = $maxQty; - } - } - } - - if ($qty == 0) { - return 0; - } - - $limitedElementsQty = array( - Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME => array( - 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME]], - 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME]], - 'limit' => 1 - ), - Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME => array( - 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME]], - 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME]], - 'limit' => 1 - ), - Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE => array( - 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE]], - 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE]], - 'limit' => $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_MISSILE_SILO]] * 10 - ), - Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE => array( - 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE]], - 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE]], - 'limit' => $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_MISSILE_SILO]] * 5 - ) - ); - - if (in_array($shipId, array_keys($limitedElementsQty))) { - foreach ($this->_queue as $element) { - if ($element['ship_id'] != $shipId) { - continue; - } - - $limitedElementsQty[$shipId]['requested'] = Math::add($limitedElementsQty[$shipId]['requested'], $element['qty']); - if (Math::comp($limitedElementsQty[$shipId]['requested'], $limitedElementsQty[$shipId]['limit']) >= 0) { - return 0; - } - } - if (Math::comp($limitedElementsQty[$shipId]['current'], $limitedElementsQty[$shipId]['limit']) >= 0) { - return 0; - } - if (Math::comp($qty, $limitedElementsQty[$shipId]['limit']) >= 0) { - return $limitedElementsQty[$shipId]['limit']; - } - } - - return $qty; + return $this->_builder->getMaximumBuildableElementsCount($shipId); } - protected function _getResourcesNeeded($shipId, $qty) + public function getResourcesNeeded($shipId, $qty) { - $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); - - $resourcesNeeded = array(); - foreach ($this->_resourcesTypes as $resourceId) { - if (isset($prices[$shipId]) && isset($prices[$shipId][$resourceId]) && $prices[$shipId][$resourceId] > 0) { - $resourcesNeeded[$resourceId] = Math::mul($prices[$shipId][$resourceId], $qty); - } - } - - return $resourcesNeeded; + return $this->_builder->getResourcesNeeded(); } public function getBuildTime($shipId, $qty) { - $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); - $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); - $types = Legacies_Empire_Model_Game_Types::getSingleton(); - $gameConfig = Legacies_Core_Model_Config::getSingleton(); - - $scale = 30; - - $totalCost = Math::mul(Math::add($prices[$shipId][Legacies_Empire::RESOURCE_METAL], $prices[$shipId][Legacies_Empire::RESOURCE_CRISTAL]), $qty, $scale); - $speedFactor = $gameConfig->getData('game_speed'); - - $shipyardSpeedup = Math::div(1, Math::add($this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_SHIPYARD]], 1, $scale), $scale); - $naniteSpeedup = Math::pow(.5, $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_NANITE_FACTORY]], $scale); - $structuresSpeedup = Math::mul($shipyardSpeedup, $naniteSpeedup, $scale); - - $officerSpeedup = 1; - if (in_array($shipId, $types[Legacies_Empire::TYPE_SHIP])) { - $officerSpeedup = 1 - ($this->_currentUser['rpg_technocrate'] * .05); - } else if (in_array($shipId, $types[Legacies_Empire::TYPE_SPECIAL])) { - $officerSpeedup = 1 - ($this->_currentUser['rpg_technocrate'] * .05); - } else if (in_array($shipId, $types[Legacies_Empire::TYPE_DEFENSE])) { - $officerSpeedup = 1 - ($this->_currentUser['rpg_defenseur'] * .375); - } - - $baseTime = ($totalCost / $speedFactor) * $structuresSpeedup; - - return $baseTime * $officerSpeedup * 3600; + $this->_builder->getBuildTime($shipId, $qty); } public static function planetUpdateListener($eventData) diff --git a/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard/Builder.php b/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard/Builder.php index ab36ce5..101d232 100644 --- a/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard/Builder.php +++ b/includes/application/code/community/Legacies/Empire/Model/Planet/Building/Shipyard/Builder.php @@ -3,20 +3,268 @@ class Legacies_Empire_Model_Planet_Building_Shipyard_Builder extends Legacies_Empire_Model_BuilderAbstract { - public function __construct($currentPlanet, $currentUser) + public function init() { - parent::__construct($currentPlanet, $currentUser); - - $this->_unserializeQueue($currentPlanet->getData('b_hangar_id')); + $this->_unserializeQueue($this->_currentPlanet->getData('b_hangar_id')); } - public function _initItem($shipId, $qty) + /** + * @param int $buildingId + * @param int $qty + * @param int $time + */ + public function _initItem() { + $shipId = func_get_arg(0); + $qty = func_get_arg(1); + $time = func_get_arg(2); + return new Legacies_Empire_Model_Planet_Building_Shipyard_Item(array( 'ship_id' => $shipId, 'qty' => $qty, - 'created_at' => time(), - 'updated_at' => time() + 'created_at' => $time, + 'updated_at' => $time )); } -} \ No newline at end of file + + /** + * Check if a ship or defense type is actually buildable on the current + * planet, depending on the technology and buildings requirements. + * + * @param int $shipId + * @return bool + */ + public function checkAvailability($shipId) + { + $types = Legacies_Empire_Model_Game_Types::getSingleton(); + $requirements = Legacies_Empire_Model_Game_Requirements::getSingleton(); + + if (!isset($requirements[$shipId]) || empty($requirements[$shipId])) { + return true; + } + + foreach ($requirements[$shipId] as $requirement => $level) { + if ($types->is($requirement, Legacies_Empire::TYPE_BUILDING) && $this->_currentPlanet->hasElement($requirement, $level)) { + continue; + } else if ($types->is($requirement, Legacies_Empire::TYPE_RESEARCH) && $this->_currentUser->hasElement($requirement, $level)) { + continue; + } else if ($types->is($requirement, Legacies_Empire::TYPE_DEFENSE) && $this->_currentPlanet->hasElement($requirement, $level)) { + continue; + } else if ($types->is($requirement, Legacies_Empire::TYPE_SHIP) && $this->_currentPlanet->hasElement($requirement, $level)) { + continue; + } + return false; + } + + try { + // Dispatch event. Throw an exception to break the avaliability. + Legacies::dispatchEvent('planet.shipyard.check-availability', array( + 'ship_id' => $shipId, + 'shipyard' => $this, + 'planet' => $this->_currentPlanet, + 'user' => $this->_currentUser + )); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * Returns the maximum quantity of elements that are possible to build on + * the current planet. + * + * @param int $shipId + * @return int|string + */ + public function getMaximumBuildableElementsCount($shipId) + { + $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); + $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); + + $resources = array( + Legacies_Empire::RESOURCE_METAL, + Legacies_Empire::RESOURCE_CRISTAL, + Legacies_Empire::RESOURCE_DEUTERIUM, + Legacies_Empire::RESOURCE_ENERGY + ); + + $qty = 0; + foreach ($resources as $resourceId) { + if (isset($prices[$shipId]) && isset($prices[$shipId][$resourceId]) && Math::comp($prices[$shipId][$resourceId], 0) > 0) { + $maxQty = Math::floor(Math::div($this->_currentPlanet->getData($resourceId), $prices[$shipId][$resourceId])); + + if ($maxQty == 0) { + return 0; + } + + if ($qty == 0 || Math::comp($maxQty, $qty) < 0) { + $qty = $maxQty; + } + } + } + + if ($qty == 0) { + return 0; + } + + $limitedElementsQty = array( + Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME => array( + 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME]], + 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_SMALL_SHIELD_DOME]], + 'limit' => 1 + ), + Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME => array( + 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME]], + 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_DEFENSE_LARGE_SHIELD_DOME]], + 'limit' => 1 + ), + Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE => array( + 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE]], + 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_ANTIBALLISTIC_MISSILE]], + 'limit' => $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_MISSILE_SILO]] * 10 + ), + Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE => array( + 'current' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE]], + 'requested' => $this->_currentPlanet[$fields[Legacies_Empire::ID_SPECIAL_INTERPLANETARY_MISSILE]], + 'limit' => $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_MISSILE_SILO]] * 5 + ) + ); + + if (in_array($shipId, array_keys($limitedElementsQty))) { + foreach ($this->_queue as $element) { + if ($element['ship_id'] != $shipId) { + continue; + } + + $limitedElementsQty[$shipId]['requested'] = Math::add($limitedElementsQty[$shipId]['requested'], $element['qty']); + if (Math::comp($limitedElementsQty[$shipId]['requested'], $limitedElementsQty[$shipId]['limit']) >= 0) { + return 0; + } + } + if (Math::comp($limitedElementsQty[$shipId]['current'], $limitedElementsQty[$shipId]['limit']) >= 0) { + return 0; + } + if (Math::comp($qty, $limitedElementsQty[$shipId]['limit']) >= 0) { + return $limitedElementsQty[$shipId]['limit']; + } + } + + return $qty; + } + + /** + * Returns the time needed to build $qty of $shipId + * + * @param int $shipId + * @param int $qty + */ + public function getBuildingTime($shipId, $qty) + { + $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); + $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); + $types = Legacies_Empire_Model_Game_Types::getSingleton(); + $gameConfig = Legacies_Core_Model_Config::getSingleton(); + + Math::setPrecision(50); + + // FIXME: Resource dependency + $totalCost = Math::mul(Math::add($prices[$shipId][Legacies_Empire::RESOURCE_METAL], $prices[$shipId][Legacies_Empire::RESOURCE_CRISTAL]), $qty); + $speedFactor = $gameConfig->getData('game_speed'); + + // FIXME: Building dependency + $shipyardSpeedup = Math::div(1, Math::add($this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_SHIPYARD]], 1)); + $naniteSpeedup = Math::pow(.5, $this->_currentPlanet[$fields[Legacies_Empire::ID_BUILDING_NANITE_FACTORY]]); + $structuresSpeedup = Math::mul($shipyardSpeedup, $naniteSpeedup); + + // FIXME: officers + $officerSpeedup = 1; + if ($types->is($shipId, Legacies_Empire::TYPE_SHIP)) { + $officerSpeedup = 1 - ($this->_currentUser['rpg_technocrate'] * .05); + } else if ($types->is($shipId, Legacies_Empire::TYPE_SPECIAL)) { + $officerSpeedup = 1 - ($this->_currentUser['rpg_technocrate'] * .05); + } else if ($types->is($shipId, Legacies_Empire::TYPE_DEFENSE)) { + $officerSpeedup = 1 - ($this->_currentUser['rpg_defenseur'] * .375); + } + + Math::setPrecision(); + + $baseTime = ($totalCost / $speedFactor) * $structuresSpeedup; + + return (int) Math::floor($baseTime * $officerSpeedup * 3600); + } + + /** + * (non-PHPdoc) + * @see Legacies_Empire_Model_BuilderAbstract::getResourcesNeeded() + */ + public function getResourcesNeeded($shipId, $qty) + { + $prices = Legacies_Empire_Model_Game_Prices::getSingleton(); + + $resourcesNeeded = array(); + foreach ($this->_resourcesTypes as $resourceId) { + if (isset($prices[$shipId]) && isset($prices[$shipId][$resourceId]) && $prices[$shipId][$resourceId] > 0) { + $resourcesNeeded[$resourceId] = Math::mul($prices[$shipId][$resourceId], $qty); + } + } + + return $resourcesNeeded; + } + + /** + * Update the contruction queue. + * + * @return Legacies_Empire_Model_Planet_Building_Shipyard + */ + public function updateQueue($time = null) + { + $fields = Legacies_Empire_Model_Game_FieldsAlias::getSingleton(); + + if ($time === null) { + $time = Legacies::now(); + } + $elapsedTime = $time - $this->_currentPlanet->getLastUpdate(); + + // Dispatch event + Legacies::dispatchEvent('planet.shipyard.update-queue.before', array( + 'shipyard' => $this, + 'planet' => $this->_currentPlanet, + 'user' => $this->_currentUser + )); + + + foreach ($this as $element) { + $shipId = $element->getData('ship_id'); + $qty = $element->getData('qty'); + $buildTime = $this->getBuildingTime($shipId, $qty); + + if ($elapsedTime >= $buildTime) { + $this->_currentPlanet[$fields[$shipId]] = Math::add($this->_currentPlanet[$fields[$shipId]], $qty); + $elapsedTime -= $buildTime; + $this->dequeue($element->getIndex()); + continue; + } + + $timeRatio = $elapsedTime / $buildTime; + $itemsBuilt = Math::mul($timeRatio, $qty); + + $element->setData('updated_at', $time); + $element->setData('qty', Math::sub($qty, $itemsBuilt)); + $this->_currentPlanet->setData($fields[$shipId], Math::add($this->_currentPlanet->getData($fields[$shipId]), $itemsBuilt)); + break; + } + + $this->_currentPlanet->setData('b_hangar_id', $this->serialize()); + + // Dispatch event + Legacies::dispatchEvent('planet.shipyard.update-queue.after', array( + 'shipyard' => $this, + 'planet' => $this->_currentPlanet, + 'user' => $this->_currentUser + )); + + return $this; + } +}; \ No newline at end of file diff --git a/includes/application/test/UpdatePlanet.php b/includes/application/test/UpdatePlanet.php index bc772d5..fa5e8bc 100644 --- a/includes/application/test/UpdatePlanet.php +++ b/includes/application/test/UpdatePlanet.php @@ -9,7 +9,18 @@ if (!extension_loaded('xdebug')) { $planet = new Legacies_Empire_Model_Planet(array( 'last_update' => 0, 'planet_type' => 1, - 'b_building' => (3600 * 10000), + + 'b_hangar_id' => serialize(array(array( + 'ship_id' => Legacies_Empire::ID_SHIP_LIGHT_TRANSPORT, + 'qty' => 1, + 'created_at' => 0, + 'updated_at' => 0 + ), array( + 'ship_id' => Legacies_Empire::ID_SHIP_LARGE_TRANSPORT, + 'qty' => 100, + 'created_at' => 600, + 'updated_at' => 600 + ))), 'metal' => 0, 'metal_perhour' => 20, @@ -34,7 +45,7 @@ $planet = new Legacies_Empire_Model_Planet(array( 'fusion_plant' => 0, 'robot_factory' => 0, 'nano_factory' => 0, - 'hangar' => 0, + 'hangar' => 6, 'metal_store' => 5, 'crystal_store' => 5, 'deuterium_store' => 5, @@ -46,11 +57,11 @@ var_dump($planet->getAllDatas()); $planet->updateStorages(3600); -var_dump($planet->getAllDatas()); +//var_dump($planet->getAllDatas()); $planet->updateResourceProduction(3600); -var_dump($planet->getAllDatas()); +//var_dump($planet->getAllDatas()); Legacies::dispatchEvent('planet.update', array( 'planet' => $planet, @@ -59,7 +70,6 @@ Legacies::dispatchEvent('planet.update', array( var_dump($planet->getAllDatas()); -var_dump((3600 + (3600 * 200))); Legacies::dispatchEvent('planet.update', array( 'planet' => $planet, 'time' => (3600 + (3600 * 200))