#include "FireBasedProcessingBlockComponent.h" #include "Block.h" #include "ItemFilter.h" #include "Recipie.h" #include "RecipieList.h" #include "RecipieLoader.h" FireBasedProcessingBlockComponent::FireBasedProcessingBlockComponent() : BlockComponent() {} FireBasedProcessingBlockComponent::~FireBasedProcessingBlockComponent() {} void FireBasedProcessingBlockComponent::findRecipie() { RecipieList* zRecipies = Game::INSTANCE->zRecipies()->zRecipieList(recipieGroup.getText()); if (zRecipies) { zBlock->lock(); Recipie* recipie = zRecipies->zFirstRecipie(this); if (recipie) { recipie->consumeInputs(this); currentRecipie = recipie; ticksNeeded = recipie->getTicksNeeded(); } zBlock->unlock(); } } void FireBasedProcessingBlockComponent::consumeFuel() { zBlock->lock(); ItemSlot* fireStartingSlot = 0; ItemSlot* fuelSlot = 0; for (ItemSlot* slot : *zBlock) { if (slot->zStack()) { if (!burning && !fireStartingSlot && slot->getName().istGleich(fireStartingInventorySlotName) && fireStartingItemFilter->matchItem(slot->zStack()->zItem())) { fireStartingSlot = slot; } if (!fuelSlot && slot->getName().istGleich(fuelInventorySlotName) && fuelItemFilter->matchItem(slot->zStack()->zItem())) { fuelSlot = slot; } if (fuelSlot && fireStartingSlot) { break; } } } if (burning) { if (fuelSlot) { ItemStack* fuelStack = fuelSlot->takeItemsOut(1, Direction::NO_DIRECTION); if (fuelStack) { // TODO: check if item is burnable and how much fuel it provides fuelBuffer += 100; fuelStack->release(); } else { if (fuelBuffer == 0) { burning = false; } } } else { if (fuelBuffer == 0) { burning = false; } } } else { if (fuelSlot && fireStartingSlot) { ItemStack* fuelStack = fuelSlot->takeItemsOut(1, Direction::NO_DIRECTION); ItemStack* fireStartingStack = fireStartingSlot->takeItemsOut(1, Direction::NO_DIRECTION); if (fuelStack && fireStartingStack) { // TODO: check if item is burnable and how much fuel it provides fuelBuffer += 100; burning = true; fuelStack->release(); fireStartingStack->release(); } } } zBlock->unlock(); } void FireBasedProcessingBlockComponent::initialize(Block* zBlock) { this->zBlock = zBlock; } bool FireBasedProcessingBlockComponent::tick(int numTicks) { bool active = 0; while (numTicks > 0) { if (!fuelBuffer) { consumeFuel(); } if (!burning) { break; } if (!currentRecipie) { findRecipie(); } bool processed = false; if (currentRecipie) { int possibleTicks = fuelBuffer / currentRecipie->getFuelPerTickNeeded(); if (!possibleTicks) { consumeFuel(); possibleTicks = fuelBuffer / currentRecipie->getFuelPerTickNeeded(); } if (possibleTicks >= numTicks) { if (numTicks >= ticksNeeded) { numTicks -= ticksNeeded; fuelBuffer -= currentRecipie->getFuelPerTickNeeded() * ticksNeeded; zBlock->lock(); currentRecipie->produceOutputs(this); zBlock->unlock(); ticksNeeded = 0; currentRecipie = 0; } else { ticksNeeded -= numTicks; fuelBuffer -= currentRecipie->getFuelPerTickNeeded() * numTicks; numTicks = 0; } processed = true; } else { if (possibleTicks >= ticksNeeded) { numTicks -= ticksNeeded; fuelBuffer -= currentRecipie->getFuelPerTickNeeded() * ticksNeeded; zBlock->lock(); currentRecipie->produceOutputs(this); zBlock->unlock(); ticksNeeded = 0; currentRecipie = 0; processed = true; } else { numTicks -= possibleTicks; fuelBuffer -= currentRecipie->getFuelPerTickNeeded() * possibleTicks; ticksNeeded -= possibleTicks; processed = possibleTicks > 0; } } } if (!processed) { // burning without recipie if (fuelBuffer >= numTicks) { fuelBuffer -= numTicks; numTicks = 0; } else { numTicks -= fuelBuffer; fuelBuffer = 0; } } active = 1; } return active; } Framework::XML::Element* FireBasedProcessingBlockComponent::getUIML() const { return nullptr; } bool FireBasedProcessingBlockComponent::isAllAvailable( Framework::RCArray& inputs) { return zBlock->isAllAvailable(inputs, inputInventorySlotName); } bool FireBasedProcessingBlockComponent::hasFreeSpace( const Item* zItem, int amount) { int addable = zBlock->numberOfAddableItems( zItem, NO_DIRECTION, inputInventorySlotName); return addable >= amount; } void FireBasedProcessingBlockComponent::consume( Framework::RCArray& inputs) { zBlock->consume(inputs, inputInventorySlotName); } void FireBasedProcessingBlockComponent::addCraftingResult(ItemStack* zStack) { TargetSlotNameItemFilter filter(outputInventorySlotName); zBlock->unsaveAddItem(zStack, NO_DIRECTION, &filter); } Framework::Vec3 FireBasedProcessingBlockComponent::getStorageLocation() const { return zBlock->getLocation(); } int FireBasedProcessingBlockComponent::getStorageDimensionId() const { return zBlock->getDimensionId(); } void FireBasedProcessingBlockComponent::loadComponent( Framework::StreamReader* zReader) { zReader->lese((char*)&ticksNeeded, 4); zReader->lese((char*)&fuelBuffer, 4); zReader->lese((char*)&burning, 1); int index = 0; zReader->lese((char*)&index, 4); if (index >= 0) { // TODO: add unique recipie ids to enshure correct loading after // recipies were changed, added or removed RecipieList* recipies = Game::INSTANCE->zRecipies()->zRecipieList(recipieGroup); if (recipies && index < recipies->getRecipieCount()) { currentRecipie = recipies->zRecipie(index); } } } void FireBasedProcessingBlockComponent::saveComponent( Framework::StreamWriter* zWriter) const { zWriter->schreibe((char*)&ticksNeeded, 4); zWriter->schreibe((char*)&fuelBuffer, 4); zWriter->schreibe((char*)&burning, 1); int index = -1; if (currentRecipie) { // TODO: add unique recipie ids to enshure correct loading after // recipies were changed, added or removed RecipieList* recipies = Game::INSTANCE->zRecipies()->zRecipieList(recipieGroup); if (recipies) { index = recipies->getRecipieIndex(currentRecipie); } } zWriter->schreibe((char*)&index, 4); } FireBasedProcessingBlockComponentFactory:: FireBasedProcessingBlockComponentFactory() : SubTypeFactory() {} FireBasedProcessingBlockComponent* FireBasedProcessingBlockComponentFactory::fromJson( Framework::JSON::JSONObject* zJson) const { FireBasedProcessingBlockComponent* component = new FireBasedProcessingBlockComponent(); if (zJson->hasValue("fireStartingItemFilter")) { component->fireStartingItemFilter = Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("fireStartingItemFilter")); } else { component->fireStartingItemFilter = new AnyItemFilter(); } if (zJson->hasValue("fuelItemFilter")) { component->fuelItemFilter = Game::INSTANCE->zTypeRegistry()->fromJson( zJson->zValue("fuelItemFilter")); } else { component->fuelItemFilter = new AnyItemFilter(); } component->recipieGroup = zJson->zValue("recipieGroup")->asString()->getString(); component->fuelInventorySlotName = zJson->zValue("fuelInventorySlotName")->asString()->getString(); component->fireStartingInventorySlotName = zJson->zValue("fireStartingInventorySlotName") ->asString() ->getString(); component->inputInventorySlotName = zJson->zValue("inputInventorySlotName")->asString()->getString(); component->outputInventorySlotName = zJson->zValue("outputInventorySlotName")->asString()->getString(); return component; } Framework::JSON::JSONObject* FireBasedProcessingBlockComponentFactory::toJsonObject( FireBasedProcessingBlockComponent* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); result->addValue("fireStartingItemFilter", Game::INSTANCE->zTypeRegistry()->toJson( zObject->fireStartingItemFilter)); result->addValue("fuelItemFilter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->fuelItemFilter)); result->addValue("recipieGroup", new Framework::JSON::JSONString(zObject->recipieGroup.getText())); result->addValue("fuelInventorySlotName", new Framework::JSON::JSONString( zObject->fuelInventorySlotName.getText())); result->addValue("fireStartingInventorySlotName", new Framework::JSON::JSONString( zObject->fireStartingInventorySlotName.getText())); result->addValue("inputInventorySlotName", new Framework::JSON::JSONString( zObject->inputInventorySlotName.getText())); result->addValue("outputInventorySlotName", new Framework::JSON::JSONString( zObject->outputInventorySlotName.getText())); return result; } JSONObjectValidationBuilder* FireBasedProcessingBlockComponentFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return builder ->withRequiredAttribute("fireStartingItemFilter", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("fuelItemFilter", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("recipieGroup", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("fuelInventorySlotName", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("fireStartingInventorySlotName", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("inputInventorySlotName", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("outputInventorySlotName", Game::INSTANCE->zTypeRegistry()->getValidator()); return builder; } const char* FireBasedProcessingBlockComponentFactory::getTypeToken() const { return "fireBasedProcessing"; }