creationTime = microtime(true); $this->source = $source; } /** * @return Player */ public function getSource() : Player{ return $this->source; } public function getCreationTime() : float{ return $this->creationTime; } /** * @return Inventory[] */ public function getInventories() : array{ return $this->inventories; } /** * @return InventoryAction[] */ public function getActions() : array{ return $this->actions; } public function addAction(InventoryAction $action){ if(isset($this->actions[spl_object_hash($action)])){ return; } $this->actions[spl_object_hash($action)] = $action; if($action instanceof SlotChangeAction){ $action->setInventoryFrom($this->source); $this->inventories[spl_object_hash($action->getInventory())] = $action->getInventory(); } } /** * @param Item[] $needItems * @param Item[] $haveItems * * @return bool */ protected function matchItems(array &$needItems, array &$haveItems) : bool{ foreach($this->actions as $key => $action){ if($action->getTargetItem()->getId() !== Item::AIR){ $needItems[] = $action->getTargetItem(); } if(!$action->isValid($this->source)){ return false; } if($action->getSourceItem()->getId() !== Item::AIR){ $haveItems[] = $action->getSourceItem(); } } foreach($needItems as $i => $needItem){ foreach($haveItems as $j => $haveItem){ if($needItem->equals($haveItem)){ $amount = min($needItem->getCount(), $haveItem->getCount()); $needItem->setCount($needItem->getCount() - $amount); $haveItem->setCount($haveItem->getCount() - $amount); if($haveItem->getCount() === 0){ unset($haveItems[$j]); } if($needItem->getCount() === 0){ unset($needItems[$i]); break; } } } } return true; } public function canExecute() : bool{ $haveItems = []; $needItems = []; return $this->matchItems($needItems, $haveItems) and count($this->actions) > 0 and count($haveItems) === 0 and count($needItems) === 0; } /** * @return bool */ public function execute() : bool{ if($this->hasExecuted() or !$this->canExecute()){ return false; } Server::getInstance()->getPluginManager()->callEvent($ev = new InventoryTransactionEvent($this)); if($ev->isCancelled()){ return false; } foreach($this->actions as $action){ if($action->execute($this->source)){ $action->onExecuteSuccess($this->source); }else{ $action->onExecuteFail($this->source); } } $this->hasExecuted = true; return true; } public function hasExecuted() : bool{ return $this->hasExecuted; } }