#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 (this->filter) this->filter->release(); this->filter = filter; } ItemFilter* RecipieInput::zFilter() const { return filter; } void RecipieInput::setModifier(ItemModifier* modifier) { if (this->modifier) this->modifier->release(); this->modifier = modifier; } ItemModifier* RecipieInput::zModifier() const { return modifier; } void RecipieInput::setAmount(int amount) { this->amount = amount; } int RecipieInput::getAmount() const { return amount; } RecipieInputFactory::RecipieInputFactory() : ObjectTypeFactory() {} RecipieInput* RecipieInputFactory::fromJson( Framework::JSON::JSONObject* zJson) const { RecipieInput* result = new RecipieInput(); result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("filter"))); result->setModifier(Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier"))); result->setAmount( (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber()); return result; } Framework::JSON::JSONObject* RecipieInputFactory::toJsonObject( RecipieInput* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); result->addValue( "filter", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter())); result->addValue("modifier", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier())); result->addValue("amount", new Framework::JSON::JSONNumber((double)zObject->getAmount())); return result; } 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() : ObjectTypeFactory() {} RecipieOutput* RecipieOutputFactory::fromJson( Framework::JSON::JSONObject* zJson) const { RecipieOutput* result = new RecipieOutput(); result->setItemTypeId(Game::INSTANCE->getItemTypeId( zJson->asObject()->zValue("itemType")->asString()->getString())); result->setAmount( (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber()); result->setModifier(Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier"))); return result; } Framework::JSON::JSONObject* RecipieOutputFactory::toJsonObject( RecipieOutput* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); result->addValue("itemType", new Framework::JSON::JSONString( Game::INSTANCE->zItemType(zObject->getItemTypeId())->getName())); result->addValue("amount", new Framework::JSON::JSONNumber((double)zObject->getAmount())); result->addValue("modifier", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zModifier())); return result; } JSONObjectValidationBuilder* RecipieOutputFactory::addToValidator( JSONObjectValidationBuilder* builder) const { Framework::JSON::JSONObject* defaultModifier = new Framework::JSON::JSONObject(); defaultModifier->addValue( "type", new Framework::JSON::JSONString("doNothing")); return builder ->withRequiredAttribute("itemType", Game::INSTANCE->zTypeRegistry()->getValidator( ItemTypeNameFactory::TYPE_ID)) ->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(); } UnshapedRecipie* UnshapedRecipieFactory::fromJson( Framework::JSON::JSONObject* zJson) const { UnshapedRecipie* result = RecipieFactory::fromJson(zJson); for (Framework::JSON::JSONValue* input : *zJson->zValue("inputs")->asArray()) { result->addInput( Game::INSTANCE->zTypeRegistry()->fromJson(input)); } return result; } Framework::JSON::JSONObject* UnshapedRecipieFactory::toJsonObject( UnshapedRecipie* zObject) const { Framework::JSON::JSONObject* result = RecipieFactory::toJsonObject(zObject); Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray(); for (RecipieInput* input : zObject->getInputs()) { inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(input)); } result->addValue("inputs", inputs); return result; } JSONObjectValidationBuilder* UnshapedRecipieFactory::addToValidator( JSONObjectValidationBuilder* builder) const { return RecipieFactory::addToValidator( builder->withRequiredArray("inputs") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishArray()); } const char* 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(); } ShapedRecipie* ShapedRecipieFactory::fromJson( Framework::JSON::JSONObject* zJson) const { ShapedRecipie* result = RecipieFactory::fromJson(zJson); int width = (int)zJson->zValue("width")->asNumber()->getNumber(); int height = (int)zJson->zValue("height")->asNumber()->getNumber(); for (int i = 0; i < width * height; i++) { result->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 << " input " << input->toString() << " will be ignored."; continue; } result->setInput(y * width + x, Game::INSTANCE->zTypeRegistry()->fromJson( input->asObject()->zValue("input"))); } result->setWidth((int)zJson->zValue("width")->asNumber()->getNumber()); result->setHeight((int)zJson->zValue("height")->asNumber()->getNumber()); return result; } Framework::JSON::JSONObject* ShapedRecipieFactory::toJsonObject( ShapedRecipie* zObject) const { Framework::JSON::JSONObject* result = RecipieFactory::toJsonObject(zObject); result->addValue( "width", new Framework::JSON::JSONNumber(zObject->getWidth())); result->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); } result->addValue("inputs", inputs); return result; } 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()); } const char* ShapedRecipieFactory::getTypeToken() const { return "shaped"; }