#include "Recipie.h" #include #include "CraftingStorage.h" #include "Game.h" #include "Item.h" RecipieInput::RecipieInput() : ReferenceCounter(), filter(0), modifier(0), amount(0) {} RecipieInput::~RecipieInput() { if (filter) filter->release(); if (modifier) modifier->release(); } void RecipieInput::setFilter(ItemFilter* filter) { if (filter) filter->release(); filter = filter; } ItemFilter* RecipieInput::zFilter() const { return filter; } void RecipieInput::setModifier(ItemModifier* modifier) { if (modifier) modifier->release(); modifier = modifier; } ItemModifier* RecipieInput::zModifier() const { return modifier; } void RecipieInput::setAmount(int amount) { this->amount = amount; } int RecipieInput::getAmount() const { return amount; } RecipieInputFactory::RecipieInputFactory() : TypeFactory() {} RecipieInput* RecipieInputFactory::createValue( Framework::JSON::JSONObject* zJson) const { return new RecipieInput(); } void RecipieInputFactory::fromJson( RecipieInput* zResult, Framework::JSON::JSONObject* zJson) const { zResult->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("filter"))); zResult->setModifier( Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier"))); zResult->setAmount( (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber()); } void RecipieInputFactory::toJson( RecipieInput* zObject, Framework::JSON::JSONObject* zResult) const { zResult->addValue( "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter())); zResult->addValue("modifier", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier())); zResult->addValue("amount", new Framework::JSON::JSONNumber((double)zObject->getAmount())); } JSONObjectValidationBuilder* RecipieInputFactory::addToValidator( JSONObjectValidationBuilder* builder) const { Framework::JSON::JSONObject* defaultModifier = new Framework::JSON::JSONObject(); defaultModifier->addValue( "type", new Framework::JSON::JSONString("consume")); return builder ->withRequiredAttribute("filter", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredAttribute("modifier", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredObject("modifier") ->withRequiredString("type") ->withExactMatch("consume") ->finishString() ->withDefault(defaultModifier) ->finishObject() ->withRequiredNumber("amount") ->whichIsGreaterOrEqual(1.0) ->withDefault(1.0) ->finishNumber(); } RecipieOutput::RecipieOutput() : ReferenceCounter(), itemTypeId(0), amount(0), modifier(0) {} RecipieOutput::~RecipieOutput() { modifier->release(); } void RecipieOutput::setItemTypeId(int itemTypeId) { this->itemTypeId = itemTypeId; } int RecipieOutput::getItemTypeId() const { return itemTypeId; } void RecipieOutput::setAmount(int amount) { this->amount = amount; } int RecipieOutput::getAmount() const { return amount; } void RecipieOutput::setModifier(ItemModifier* modifier) { if (this->modifier) this->modifier->release(); this->modifier = modifier; } ItemModifier* RecipieOutput::zModifier() const { return modifier; } Item* RecipieOutput::createItem() const { Item* result = Game::INSTANCE->zItemType(itemTypeId)->createItem(); if (result) { modifier->applyOn(result); } return result; } RecipieOutputFactory::RecipieOutputFactory() : TypeFactory() {} RecipieOutput* RecipieOutputFactory::createValue( Framework::JSON::JSONObject* zJson) const { return new RecipieOutput(); } void RecipieOutputFactory::fromJson( RecipieOutput* zResult, Framework::JSON::JSONObject* zJson) const { zResult->setItemTypeId(Game::INSTANCE->getItemTypeId( zJson->asObject()->zValue("itemType")->asString()->getString())); zResult->setAmount( (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber()); zResult->setModifier( Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier"))); } void RecipieOutputFactory::toJson( RecipieOutput* zObject, Framework::JSON::JSONObject* zResult) const { zResult->addValue("itemType", new Framework::JSON::JSONString( Game::INSTANCE->zItemType(zObject->getItemTypeId())->getName())); zResult->addValue("amount", new Framework::JSON::JSONNumber((double)zObject->getAmount())); zResult->addValue("modifier", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier())); } JSONObjectValidationBuilder* RecipieOutputFactory::addToValidator( JSONObjectValidationBuilder* builder) const { Framework::JSON::JSONObject* defaultModifier = new Framework::JSON::JSONObject(); defaultModifier->addValue( "type", new Framework::JSON::JSONString("doNothing")); Framework::RCArray itemTypes; for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++) { if (Game::INSTANCE->zItemType(i)) { itemTypes.add( new Framework::Text(Game::INSTANCE->zItemType(i)->getName())); } } return builder->withRequiredString("itemType") ->whichIsOneOf(itemTypes) ->finishString() ->withRequiredAttribute("modifier", Game::INSTANCE->zTypeRegistry()->getValidator()) ->withRequiredObject("modifier") ->withRequiredString("type") ->withExactMatch("doNothing") ->finishString() ->withDefault(defaultModifier) ->finishObject() ->withRequiredNumber("amount") ->whichIsGreaterOrEqual(1.0) ->withDefault(1.0) ->finishNumber(); } Recipie::Recipie() : ReferenceCounter() {} void Recipie::addOutput(RecipieOutput* outputs) { this->outputs.add(outputs); } Framework::Array Recipie::getOutput() const { Framework::Array result; for (const RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { result.add({item->zItemType()->getId(), output->getAmount(), item->getHp(), item->getMaxHp(), item->getDurability(), item->getMaxDurability()}); item->release(); } } return result; } bool Recipie::createsOutput(int itemTypeId) { for (RecipieOutput* output : outputs) { if (output->getItemTypeId() == itemTypeId) { return 1; } } return 0; } void Recipie::setGroupName(Framework::Text groupName) { this->groupName = groupName; } const Framework::RCArray& Recipie::getOutputs() const { return outputs; } Framework::Text Recipie::getGroupName() const { return groupName; } UnshapedRecipie::UnshapedRecipie() : Recipie() {} bool UnshapedRecipie::testApplicability(CraftingStorage* zStorage) { for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { if (!zStorage->hasFreeSpace(item, output->getAmount())) { item->release(); return 0; } item->release(); } } return zStorage->isAllAvailable(inputs); } void UnshapedRecipie::apply(CraftingStorage* zStorage) { zStorage->consume(inputs); for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { ItemStack* stack = new ItemStack(item, output->getAmount()); zStorage->addCraftingResult(stack); stack->release(); } } } Framework::Text UnshapedRecipie::getRecipieUIML() { Framework::Text result = ""; for (RecipieInput* input : inputs) { result.append() << "getAmount() << "\">"; if (input->zFilter()) { result.append() << "" << input->zFilter()->getLogicUIML() << ""; } result += ""; // TODO: add modifiers } result += ""; for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { result.append() << "getAmount() << "\" itemType=\"" << item->zItemType()->getId() << "\" hp=\"" << item->getHp() << "\" durability=\"" << item->getDurability() << "\" maxHp=\"" << item->getMaxHp() << "\" maxDurability=\"" << item->getMaxDurability() << "\">" << item->getTooltipUIML() << ""; item->release(); } } result += ""; return result; } void UnshapedRecipie::addInput(RecipieInput* input) { inputs.add(input); } const Framework::RCArray& UnshapedRecipie::getInputs() const { return inputs; } UnshapedRecipieFactory::UnshapedRecipieFactory() : RecipieFactory() {} UnshapedRecipie* UnshapedRecipieFactory::createValue( Framework::JSON::JSONObject* zJson) const { return new UnshapedRecipie(); } void UnshapedRecipieFactory::fromJson( UnshapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const { for (Framework::JSON::JSONValue* input : *zJson->zValue("inputs")->asArray()) { zResult->addInput( Game::INSTANCE->zTypeRegistry()->fromJson(input)); } RecipieFactory::fromJson(zResult, zJson); } void UnshapedRecipieFactory::toJson( UnshapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const { Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray(); for (RecipieInput* input : zObject->getInputs()) { inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(input)); } zResult->addValue("inputs", inputs); RecipieFactory::toJson(zObject, zResult); } JSONObjectValidationBuilder* UnshapedRecipieFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return RecipieFactory::addToValidator( builder->withRequiredArray("inputs") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishArray()); } Framework::Text UnshapedRecipieFactory::getTypeToken() const { return "unshaped"; } ShapedRecipie::ShapedRecipie() : Recipie(), width(0), height(0) {} bool ShapedRecipie::testApplicability(CraftingStorage* zStorage) { ShapedCraftingStorage* zShapedStorage = dynamic_cast(zStorage); if (!zShapedStorage) return 0; for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { if (!zShapedStorage->hasFreeSpace(item, output->getAmount())) { item->release(); return 0; } item->release(); } } return zShapedStorage->isAllAvailable(inputs, width, height); } void ShapedRecipie::apply(CraftingStorage* zStorage) { ShapedCraftingStorage* zShapedStorage = dynamic_cast(zStorage); zShapedStorage->consume(inputs, width, height); for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { ItemStack* stack = new ItemStack(item, output->getAmount()); zStorage->addCraftingResult(stack); stack->release(); } } } Framework::Text ShapedRecipie::getRecipieUIML() { Framework::Text result = ""; for (RecipieInput* input : inputs) { result.append() << "getAmount() << "\">"; if (input->zFilter()) { result.append() << "" << input->zFilter()->getLogicUIML() << ""; } result += ""; // TODO: add modifiers } result += ""; for (RecipieOutput* output : outputs) { Item* item = output->createItem(); if (item) { result.append() << "getAmount() << "\" itemType=\"" << item->zItemType()->getId() << "\" hp=\"" << item->getHp() << "\" durability=\"" << item->getDurability() << "\" maxHp=\"" << item->getMaxHp() << "\" maxDurability=\"" << item->getMaxDurability() << "\">" << item->getTooltipUIML() << ""; item->release(); } } result += ""; return result; } void ShapedRecipie::setWidth(int width) { this->width = width; } int ShapedRecipie::getWidth() const { return width; } void ShapedRecipie::setHeight(int height) { this->height = height; } int ShapedRecipie::getHeight() const { return height; } void ShapedRecipie::addInput(RecipieInput* input) { inputs.add(input); } void ShapedRecipie::setInput(int index, RecipieInput* input) { inputs.set(input, index); } const Framework::RCArray& ShapedRecipie::getInputs() const { return inputs; } ShapedRecipieFactory::ShapedRecipieFactory() : RecipieFactory() {} ShapedRecipie* ShapedRecipieFactory::createValue( Framework::JSON::JSONObject* zJson) const { return new ShapedRecipie(); } void ShapedRecipieFactory::fromJson( ShapedRecipie* zResult, Framework::JSON::JSONObject* zJson) const { int width = (int)zJson->zValue("width")->asNumber()->getNumber(); int height = (int)zJson->zValue("height")->asNumber()->getNumber(); for (int i = 0; i < width * height; i++) { zResult->addInput(new RecipieInput()); } for (Framework::JSON::JSONValue* input : *zJson->zValue("inputs")->asArray()) { int x = (int)input->asObject()->zValue("x")->asNumber()->getNumber(); int y = (int)input->asObject()->zValue("y")->asNumber()->getNumber(); if (x >= width || y >= height) { Framework::Logging::warning() << "Invalid input position in shaped recipie with width=" << width << ", height=" << height << ", x=" << x << ", y=" << y; return; } zResult->setInput(y * width + x, Game::INSTANCE->zTypeRegistry()->fromJson( input->asObject()->zValue("input"))); } zResult->setWidth((int)zJson->zValue("width")->asNumber()->getNumber()); zResult->setHeight((int)zJson->zValue("height")->asNumber()->getNumber()); RecipieFactory::fromJson(zResult, zJson); } void ShapedRecipieFactory::toJson( ShapedRecipie* zObject, Framework::JSON::JSONObject* zResult) const { zResult->addValue( "width", new Framework::JSON::JSONNumber(zObject->getWidth())); zResult->addValue( "height", new Framework::JSON::JSONNumber(zObject->getHeight())); Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray(); for (int i = 0; i < zObject->getWidth() * zObject->getHeight(); i++) { Framework::JSON::JSONObject* input = new Framework::JSON::JSONObject(); input->addValue( "x", new Framework::JSON::JSONNumber(i % zObject->getHeight())); input->addValue( "y", new Framework::JSON::JSONNumber(i / zObject->getHeight())); input->addValue("input", Game::INSTANCE->zTypeRegistry()->toJson(zObject->getInputs().z(i))); inputs->addValue(input); } zResult->addValue("inputs", inputs); RecipieFactory::toJson(zObject, zResult); } JSONObjectValidationBuilder* ShapedRecipieFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return RecipieFactory::addToValidator( builder->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0.0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0.0) ->finishNumber() ->withRequiredAttribute("input", Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishObject() ->finishArray() ->withRequiredNumber("width") ->whichIsGreaterOrEqual(1.0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterOrEqual(1.0) ->finishNumber()); } Framework::Text ShapedRecipieFactory::getTypeToken() const { return "shaped"; }