|
@@ -0,0 +1,388 @@
|
|
|
|
|
+#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<RecipieInput>& 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<RecipieInput>& inputs)
|
|
|
|
|
+{
|
|
|
|
|
+ zBlock->consume(inputs, inputInventorySlotName);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void FireBasedProcessingBlockComponent::addCraftingResult(ItemStack* zStack)
|
|
|
|
|
+{
|
|
|
|
|
+ TargetSlotNameItemFilter filter(outputInventorySlotName);
|
|
|
|
|
+ zBlock->unsaveAddItem(zStack, NO_DIRECTION, &filter);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+Framework::Vec3<float>
|
|
|
|
|
+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<ItemFilter>(
|
|
|
|
|
+ zJson->zValue("fireStartingItemFilter"));
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ component->fireStartingItemFilter = new AnyItemFilter();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (zJson->hasValue("fuelItemFilter"))
|
|
|
|
|
+ {
|
|
|
|
|
+ component->fuelItemFilter
|
|
|
|
|
+ = Game::INSTANCE->zTypeRegistry()->fromJson<ItemFilter>(
|
|
|
|
|
+ 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<ItemFilter>())
|
|
|
|
|
+ ->withRequiredAttribute("fuelItemFilter",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<ItemFilter>())
|
|
|
|
|
+ ->withRequiredAttribute("recipieGroup",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>())
|
|
|
|
|
+ ->withRequiredAttribute("fuelInventorySlotName",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>())
|
|
|
|
|
+ ->withRequiredAttribute("fireStartingInventorySlotName",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>())
|
|
|
|
|
+ ->withRequiredAttribute("inputInventorySlotName",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>())
|
|
|
|
|
+ ->withRequiredAttribute("outputInventorySlotName",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>());
|
|
|
|
|
+ return builder;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const char* FireBasedProcessingBlockComponentFactory::getTypeToken() const
|
|
|
|
|
+{
|
|
|
|
|
+ return "fireBasedProcessing";
|
|
|
|
|
+}
|