#include "Recipie.h" #include "CraftingStorage.h" #include "Game.h" #include "Item.h" RecipieInput::RecipieInput( ItemFilter* filter, ItemModifier* modifier, int amount) : ReferenceCounter(), filter(filter), modifier(modifier), amount(amount) {} RecipieInput::~RecipieInput() { if (filter) filter->release(); if (modifier) modifier->release(); } ItemFilter* RecipieInput::zFilter() const { return filter; } ItemModifier* RecipieInput::zModifier() const { return modifier; } int RecipieInput::getAmount() const { return amount; } RecipieInputFactory::RecipieInputFactory() : TypeFactory() {} RecipieInput* RecipieInputFactory::fromJson( Framework::JSON::JSONValue* zJson) const { return new RecipieInput( Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("filter")), Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier")), (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber()); } Framework::JSON::JSONValue* RecipieInputFactory::toJson( 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; } Framework::JSON::Validator::JSONValidator* RecipieInputFactory::getValidator() const { Framework::JSON::JSONObject* defaultModifier = new Framework::JSON::JSONObject(); defaultModifier->addValue( "type", new Framework::JSON::JSONString("consume")); return Framework::JSON::Validator::JSONValidator::buildForObject() ->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() ->finishObject(); } RecipieOutput::RecipieOutput(int itemTypeId, int amount, ItemModifier* modifier) : ReferenceCounter(), itemTypeId(itemTypeId), amount(amount), modifier(modifier) {} RecipieOutput::~RecipieOutput() { modifier->release(); } int RecipieOutput::getItemTypeId() const { return itemTypeId; } int RecipieOutput::getAmount() const { return amount; } 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::fromJson( Framework::JSON::JSONValue* zJson) const { return new RecipieOutput( Game::INSTANCE->getItemTypeId( zJson->asObject()->zValue("itemType")->asString()->getString()), (int)zJson->asObject()->zValue("amount")->asNumber()->getNumber(), Game::INSTANCE->zTypeRegistry()->fromJson( zJson->asObject()->zValue("modifier"))); } Framework::JSON::JSONValue* RecipieOutputFactory::toJson( 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; } Framework::JSON::Validator::JSONValidator* RecipieOutputFactory::getValidator() 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 Framework::JSON::Validator::JSONValidator::buildForObject() ->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() ->finishObject(); } Recipie::Recipie( Framework::RCArray outputs, Framework::Text groupName) : ReferenceCounter(), groupName(groupName), outputs(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; } const Framework::RCArray& Recipie::getOutputs() const { return outputs; } Framework::Text Recipie::getGroupName() const { return groupName; } UnshapedRecipie::UnshapedRecipie(Framework::RCArray inputs, Framework::RCArray outputs, Framework::Text groupName) : Recipie(outputs, groupName), inputs(inputs) {} 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; } const Framework::RCArray& UnshapedRecipie::getInputs() const { return inputs; } UnshapedRecipieFactory::UnshapedRecipieFactory() : SubTypeFactory() {} UnshapedRecipie* UnshapedRecipieFactory::fromJson( Framework::JSON::JSONObject* zJson) const { Framework::RCArray inputs; Framework::RCArray outputs; for (Framework::JSON::JSONValue* input : *zJson->zValue("inputs")->asArray()) { inputs.add( Game::INSTANCE->zTypeRegistry()->fromJson(input)); } for (Framework::JSON::JSONValue* output : *zJson->zValue("outputs")->asArray()) { outputs.add( Game::INSTANCE->zTypeRegistry()->fromJson(output)); } return new UnshapedRecipie( inputs, outputs, zJson->zValue("group")->asString()->getString()); } Framework::JSON::JSONObject* UnshapedRecipieFactory::toJson( UnshapedRecipie* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); Framework::JSON::JSONArray* inputs = new Framework::JSON::JSONArray(); for (RecipieInput* input : zObject->getInputs()) { inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(input)); } result->addValue("inputs", inputs); Framework::JSON::JSONArray* outputs = new Framework::JSON::JSONArray(); for (RecipieOutput* output : zObject->getOutputs()) { inputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(output)); } result->addValue("outputs", outputs); result->addValue( "group", new Framework::JSON::JSONString(zObject->getGroupName())); return nullptr; } Framework::JSON::Validator::JSONValidator* UnshapedRecipieFactory::getValidator( Framework::JSON::Validator::ObjectValidationBuilder< Framework::JSON::Validator::JSONValidator>* builder) const { return builder->withRequiredArray("inputs") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishArray() ->withRequiredArray("outputs") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishArray() ->withRequiredString("group") ->finishString() ->finishObject(); } Framework::Text UnshapedRecipieFactory::getTypeToken() const { return "unshaped"; } ShapedRecipie::ShapedRecipie(int width, int height, Framework::RCArray inputs, Framework::RCArray outputs, Framework::Text groupName) : Recipie(outputs, groupName), inputs(inputs), width(width), height(height) { while (this->inputs.getEintragAnzahl() < width * height) { this->inputs.add(new RecipieInput(0, 0, 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; } int ShapedRecipie::getWidth() const { return width; } int ShapedRecipie::getHeight() const { return height; } const Framework::RCArray& ShapedRecipie::getInputs() const { return inputs; } ShapedRecipieFactory::ShapedRecipieFactory() : SubTypeFactory() {} ShapedRecipie* ShapedRecipieFactory::fromJson( Framework::JSON::JSONObject* zJson) const { int width = (int)zJson->zValue("width")->asNumber()->getNumber(); int height = (int)zJson->zValue("height")->asNumber()->getNumber(); Framework::RCArray inputs; for (int i = 0; i < width * height; i++) { inputs.add(new RecipieInput(0, 0, 0)); } 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) { std::cout << "Invalid input position in shaped recipie with width=" << width << ", height=" << height << "\n" << (x >= width ? x : y) << "\n"; return 0; } inputs.set(Game::INSTANCE->zTypeRegistry()->fromJson( input->asObject()->zValue("input")), y * width + x); } Framework::RCArray outputs; for (Framework::JSON::JSONValue* output : *zJson->zValue("outputs")->asArray()) { outputs.add( Game::INSTANCE->zTypeRegistry()->fromJson(output)); } return new ShapedRecipie( (int)zJson->zValue("width")->asNumber()->getNumber(), (int)zJson->zValue("height")->asNumber()->getNumber(), inputs, outputs, zJson->zValue("group")->asString()->getString()); } Framework::JSON::JSONObject* ShapedRecipieFactory::toJson( ShapedRecipie* zObject) const { Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject(); 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); Framework::JSON::JSONArray* outputs = new Framework::JSON::JSONArray(); for (RecipieOutput* output : zObject->getOutputs()) { outputs->addValue(Game::INSTANCE->zTypeRegistry()->toJson(output)); } result->addValue("outputs", outputs); result->addValue( "group", new Framework::JSON::JSONString(zObject->getGroupName())); return result; } Framework::JSON::Validator::JSONValidator* ShapedRecipieFactory::getValidator( Framework::JSON::Validator::ObjectValidationBuilder< Framework::JSON::Validator::JSONValidator>* builder) const { return builder->withRequiredArray("inputs") ->addAcceptedObjectInArray() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0.0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0.0) ->finishNumber() ->withRequiredAttribute("input", Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishObject() ->finishArray() ->withRequiredArray("outputs") ->addAcceptedTypeInArray( Game::INSTANCE->zTypeRegistry()->getValidator()) ->finishArray() ->withRequiredNumber("width") ->whichIsGreaterOrEqual(1.0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterOrEqual(1.0) ->finishNumber() ->withRequiredString("group") ->finishString() ->finishObject(); } Framework::Text ShapedRecipieFactory::getTypeToken() const { return "shaped"; }