#include "RecipieLoader.h" #include #include #include #include "Game.h" #include "ItemType.h" using namespace Framework::JSON; using namespace Validator; RecipieLoader::RecipieLoader() : Framework::ReferenceCounter(), validator(0) {} RecipieLoader::~RecipieLoader() { if (validator) validator->release(); } void RecipieLoader::loadRecipies(const char* path) { std::cout << "loading recipies from '" << path << "'" << std::endl; Framework::Datei d; d.setDatei(path); if (d.istOrdner()) { Framework::RCArray* files = d.getDateiListe(); for (Framework::Text* f : *files) loadRecipies(Framework::Text(path) + "/" + *f); files->release(); } else { JSONValue* json = loadJSONFromFile(path); JSONValidator* validator = zRecipieValidator(); Framework::RCArray invalidParts; JSONValue* valid = validator->getValidParts(json, &invalidParts); for (JSONValidationResult* invalidPart : invalidParts) { invalidPart->printInvalidInfo(); } json->release(); int count = 0; if (valid) { for (JSONValue* recipie : *valid->asArray()) loadRecipie(recipie->asObject()); count = valid->asArray()->getLength(); valid->release(); } std::cout << count << " recipies were loaded.\n"; } } void RecipieLoader::loadRecipie(JSONObject* zRecipie) { Framework::Text group = zRecipie->zValue("group")->asString()->getString(); if (zRecipie->zValue("type")->asString()->getString().istGleich("shaped")) { int width = (int)zRecipie->zValue("width")->asNumber()->getNumber(); int height = (int)zRecipie->zValue("height")->asNumber()->getNumber(); ShapedRecipie* recipie = new ShapedRecipie(width, height); for (JSONValue* input : *zRecipie->zValue("inputs")->asArray()) { int x = (int)input->asObject()->zValue("x")->asNumber()->getNumber(); int y = (int)input->asObject()->zValue("y")->asNumber()->getNumber(); ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject()); CombinedItemModifier* resultingModifier = new CombinedItemModifier(); for (JSONValue* modifier : *input->asObject()->zValue("modifiers")->asArray()) resultingModifier->addModifier( loadModifier(modifier->asObject())); recipie->setIngredient(x, y, filter, resultingModifier); } int outputCount = (int)zRecipie->asObject() ->zValue("outputCount") ->asNumber() ->getNumber(); Framework::Text outputType = zRecipie->asObject() ->zValue("output") ->asObject() ->zValue("itemType") ->asString() ->getString(); Item* item = 0; for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++) { if (Game::INSTANCE->zItemType(i) && Game::INSTANCE->zItemType(i)->getName().istGleich( outputType)) { item = Game::INSTANCE->zItemType(i)->createItem(); break; } } recipie->addOutput(item, outputCount); if (!zRecipieList(group)) registerRecipieList(group); zRecipieList(group)->addRecipie(recipie); } else if (zRecipie->zValue("type")->asString()->getString().istGleich( "unordered")) { UnshapedRecipie* recipie = new UnshapedRecipie(); for (JSONValue* input : *zRecipie->zValue("inputs")->asArray()) { int count = (int)input->asObject() ->zValue("count") ->asNumber() ->getNumber(); ItemFilter* filter = loadFilter(input->asObject()->zValue("filter")->asObject()); CombinedItemModifier* resultingModifier = new CombinedItemModifier(); for (JSONValue* modifier : *input->asObject()->zValue("modifiers")->asArray()) resultingModifier->addModifier( loadModifier(modifier->asObject())); recipie->addIngredient(filter, count, resultingModifier); } for (JSONValue* output : *zRecipie->zValue("outputs")->asArray()) { int count = (int)output->asObject() ->zValue("count") ->asNumber() ->getNumber(); Framework::Text outputType = output->asObject() ->zValue("item") ->asObject() ->zValue("itemType") ->asString() ->getString(); Item* item = 0; for (int i = 0; i < Game::INSTANCE->getItemTypeCount(); i++) { if (Game::INSTANCE->zItemType(i) && Game::INSTANCE->zItemType(i)->getName().istGleich( outputType)) { item = Game::INSTANCE->zItemType(i)->createItem(); break; } } recipie->addOutput(item, count); } if (!zRecipieList(group)) registerRecipieList(group); zRecipieList(group)->addRecipie(recipie); } } ItemFilter* RecipieLoader::loadFilter(JSONObject* zFilter) { if (zFilter->hasValue("itemType")) { Framework::Text type = zFilter->zValue("itemType")->asString()->getString(); return new TypeItemFilter( Game::INSTANCE->zItemType(ItemType::getTypeId(type))); } else if (zFilter->hasValue("operator")) { Framework::Text op = zFilter->zValue("operator")->asString()->getString(); ItemFilter* left = loadFilter(zFilter->zValue("left")->asObject()); ItemFilter* right = loadFilter(zFilter->zValue("right")->asObject()); if (op.istGleich("&&")) { return new CombinedItemFilter( left, right, [](bool a, bool b) { return a && b; }); } else if (op.istGleich("||")) { return new CombinedItemFilter( left, right, [](bool a, bool b) { return a || b; }); } else if (op.istGleich("==")) { return new CombinedItemFilter( left, right, [](bool a, bool b) { return a == b; }); } else if (op.istGleich("!=")) { return new CombinedItemFilter( left, right, [](bool a, bool b) { return a != b; }); } else { left->release(); right->release(); } } return 0; } RecipieList* RecipieLoader::zRecipieList(const char* name) const { for (RecipieList* l : lists) { if (l->getName().istGleich(name)) return l; } return 0; } void RecipieLoader::registerRecipieList(const char* name) { if (zRecipieList(name)) throw new std::invalid_argument("the recipie list already exists"); lists.add(new RecipieList(name)); } Framework::Text RecipieLoader::getCrafingUIML(const ItemType* zTargetType) { Framework::Text result = "getId() << "\">"; for (RecipieList* list : lists) { Framework::RCArray recipies; list->findRecipies(zTargetType, recipies); if (recipies.getEintragAnzahl() > 0) { result.append() << "getName(); if (list->getName().istGleich("inventory")) { result.append() << "\" itemIcon=\"" << Game::INSTANCE->getItemTypeId("Crafting Table"); } result += "\">"; for (Recipie* recipie : recipies) { result += recipie->getRecipieUIML(); } result += ""; } } result += ""; return result; } ItemModifier* RecipieLoader::loadModifier( Framework::JSON::JSONObject* zModifier) { return new AttributeItemModifier( zModifier->zValue("attribute")->asString()->getString(), zModifier->zValue("value")->asString()->getString()); } JSONValidator* RecipieLoader::zRecipieValidator() { if (validator) return validator; 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().getText())); } } JSONValidator* typeFilterValidator = JSONValidator::buildForObject() ->setObjectReferenceId("typeFilter") ->withRequiredString("itemType") ->whichIsOneOf(itemTypes) ->finishString() ->finishObject(); Framework::RCArray operators; operators.add(new Framework::Text("==")); operators.add(new Framework::Text("!=")); operators.add(new Framework::Text("&&")); operators.add(new Framework::Text("||")); JSONValidator* operatorFilterValidator = JSONValidator::buildForObject() ->setObjectReferenceId("operatorFilter") ->withRequiredString("operator") ->whichIsOneOf(operators) ->finishString() ->withRequiredAttribute( "left", JSONValidator::buildForObjectReference("typeFilter")) ->withRequiredAttribute("left", JSONValidator::buildForObjectReference("operatorFilter")) ->withRequiredAttribute( "right", JSONValidator::buildForObjectReference("typeFilter")) ->withRequiredAttribute("right", JSONValidator::buildForObjectReference("operatorFilter")) ->finishObject(); JSONValidator* outputValidator = JSONValidator::buildForObject() ->withRequiredString("itemType") ->whichIsOneOf(itemTypes) ->finishString() ->finishObject(); validator = JSONValidator::buildForArray() ->typeSpecifiedByAttribute("type") ->removeInvalidEntries() ->addAcceptedTypeInArray( JSONValidator::buildForObject() ->withRequiredString("type") ->withExactMatch("shaped") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredNumber("width") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredNumber("height") ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredAttribute("inputs", JSONValidator::buildForArray() ->withDefault(new JSONArray()) ->addAcceptedTypeInArray( JSONValidator::buildForObject() ->withRequiredNumber("x") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredNumber("y") ->whichIsGreaterOrEqual(0) ->finishNumber() ->withRequiredAttribute("filter", dynamic_cast( typeFilterValidator->getThis())) ->withRequiredAttribute("filter", dynamic_cast( operatorFilterValidator ->getThis())) ->withRequiredAttribute("modifiers", JSONValidator::buildForArray() ->withDefault(Parser::getValue( "[{\"attribute\": \"hp\", " "\"value\": \"=0\"}]") ->asArray()) ->addAcceptedTypeInArray( JSONValidator:: buildForObject() ->withRequiredString( "attribute") ->finishString() ->withRequiredString( "value") ->finishString() ->finishObject()) ->finishArray()) ->finishObject()) ->finishArray()) ->withRequiredAttribute("output", dynamic_cast( outputValidator->getThis())) ->withRequiredNumber("outputCount") ->withDefault(1) ->whichIsGreaterThen(0) ->finishNumber() ->finishObject()) ->addAcceptedTypeInArray( JSONValidator::buildForObject() ->withRequiredString("type") ->withExactMatch("unordered") ->finishString() ->withRequiredString("group") ->finishString() ->withRequiredAttribute("inputs", JSONValidator::buildForArray() ->withDefault(new JSONArray()) ->addAcceptedTypeInArray( JSONValidator::buildForObject() ->withRequiredNumber("count") ->withDefault(1) ->whichIsGreaterThen(0) ->finishNumber() ->withRequiredAttribute("filter", dynamic_cast( typeFilterValidator->getThis())) ->withRequiredAttribute("filter", dynamic_cast( operatorFilterValidator ->getThis())) ->withRequiredAttribute("modifiers", JSONValidator::buildForArray() ->withDefault(Parser::getValue( "[{\"attribute\": \"hp\", " "\"value\": \"=0\"}]") ->asArray()) ->addAcceptedTypeInArray( JSONValidator:: buildForObject() ->withRequiredString( "attribute") ->finishString() ->withRequiredString( "value") ->finishString() ->finishObject()) ->finishArray()) ->finishObject()) ->finishArray()) ->withRequiredAttribute("output", JSONValidator::buildForArray() ->addAcceptedTypeInArray( JSONValidator::buildForObject() ->withRequiredAttribute("item", dynamic_cast( outputValidator->getThis())) ->withRequiredNumber("count") ->withDefault(1) ->whichIsGreaterThen(0) ->finishNumber() ->finishObject()) ->finishArray()) ->finishObject()) ->finishArray(); typeFilterValidator->release(); operatorFilterValidator->release(); outputValidator->release(); return validator; }