freg  0.3
Free-Roaming Elementary Game
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
CraftManager.cpp
Go to the documentation of this file.
1  /* freg, Free-Roaming Elementary Game with open and interactive world
2  * Copyright (C) 2012-2014 Alexander 'mmaulwurff' Kromm
3  * mmaulwurff@gmail.com
4  *
5  * This file is part of FREG.
6  *
7  * FREG is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * FREG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with FREG. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include <QJsonDocument>
21 #include <QJsonObject>
22 #include <QFile>
23 #include "BlockManager.h"
24 #include "CraftManager.h"
25 
27 
28 // CraftItem section
29 bool CraftItem::operator<(const CraftItem &item) const {
30  return
31  BlockManager::MakeId(item.kind, item.sub) <
33 }
34 
35 // CraftList section
36 CraftList:: CraftList(const int materials_number) :
37  materialsNumber(materials_number),
38  items()
39 {}
40 
42 
43 void CraftList::operator<<(CraftItem * const new_item) {
44  items.append(new_item);
45 }
46 
47 bool CraftList::operator==(const CraftList & compared) const {
48  if ( GetMaterialsNumber() != compared.GetMaterialsNumber() ) return false;
49  for (int i=0; i<GetMaterialsNumber(); ++i) {
50  if ( memcmp(items.at(i), compared.items.at(i), sizeof(CraftItem)) ) {
51  return false;
52  }
53  }
54  return true;
55 }
56 
57 bool ItemsLess(const CraftItem * item1, const CraftItem * item2) {
58  return *item1 < *item2;
59 }
60 
61 void CraftList::LoadItems(const QJsonArray & array) {
62  for (int n=0; n<array.size(); ++n) {
63  const QJsonObject item = array.at(n).toObject();
64  items.append( new CraftItem( {item["number"].toInt(),
65  BlockManager::StringToKind(item["kind"].toString()),
66  BlockManager::StringToSub (item["sub" ].toString())} ) );
67  }
68 }
69 
70 void CraftList::Sort() { qSort(items.begin(), items.end(), ItemsLess); }
72 int CraftList::size() const { return items.size(); }
73 CraftItem * CraftList::at(const int i) const { return items.at(i); }
74 
76  for (const auto item : items) {
77  delete item;
78  }
79  items.clear();
80 }
81 // CraftManager section
82 CraftManager::CraftManager() : recipesList() {
83  for (int sub=0; sub<LAST_SUB; ++sub) {
84  QFile file(QString(":/recipes/%1.json").
85  arg(BlockManager::SubToString(sub)));
86  if ( not file.open(QIODevice::ReadOnly | QIODevice::Text) ) continue;
87  const QJsonArray recipes =
88  QJsonDocument::fromJson(file.readAll()).array();
89  for (int i=0; i<recipes.size(); ++i) {
90  const QJsonObject recipeObject = recipes.at(i).toObject();
91  const QJsonArray materials = recipeObject["materials"].toArray();
92  CraftList * const recipe = new CraftList(materials.size());
93  recipe->LoadItems(materials);
94  recipe->Sort();
95  recipe->LoadItems(recipeObject["products"].toArray());
96  recipesList[sub].append(recipe);
97  }
98  }
99 }
100 
102  for (int sub=0; sub<LAST_SUB; ++sub) {
103  for (const auto recipe : recipesList[sub]) {
104  delete recipe;
105  }
106  }
107 }
108 
109 bool CraftManager::MiniCraft(CraftItem ** item) const {
110  CraftList recipe(1);
111  recipe << *item;
112  if ( CraftSub(&recipe, DIFFERENT) ) {
113  *item = new CraftItem(
114  {recipe.at(0)->num, recipe.at(0)->kind, recipe.at(0)->sub} );
115  return true;
116  } else {
117  return false;
118  }
119 }
120 
121 bool CraftManager::Craft(CraftList * const recipe, const int sub) const {
122  return ( sub==DIFFERENT || not CraftSub(recipe, sub) ) ?
123  CraftSub(recipe, DIFFERENT) : true;
124 }
125 
126 bool CraftManager::CraftSub(CraftList * const recipe, const int sub) const {
127  recipe->Sort();
128  // find recipe and copy products from it
129  for (int i=0; i<recipesList[sub].size(); ++i) {
130  const CraftList & tried = *recipesList[sub].at(i);
131  if ( tried == *recipe ) {
132  recipe->clear();
133  for (int i=tried.GetMaterialsNumber(); i<tried.size(); ++i) {
134  *recipe << new CraftItem({tried.at(i)->num,
135  tried.at(i)->kind, tried.at(i)->sub});
136  }
137  return true;
138  }
139  }
140  return false; // suitable recipe not found
141 }
static int StringToSub(QString)
If string is not convertible to substance, returns LAST_SUB.
bool MiniCraft(CraftItem **) const
const int materialsNumber
Definition: CraftManager.h:61
int GetMaterialsNumber() const
bool CraftSub(CraftList *items, int sub) const
CraftList(int materials_number)
Nothing is made from LAST_SUB.
Definition: header.h:193
static QString SubToString(int sub)
If substance is unknown, returns "unknown_sub".
void operator<<(CraftItem *)
QList< CraftItem * > items
Definition: CraftManager.h:62
int size() const
const int kind
Definition: CraftManager.h:32
QList< CraftList * > recipesList[LAST_SUB]
Definition: CraftManager.h:78
bool operator<(const CraftItem &item) const
bool operator==(const CraftList &) const
static int StringToKind(QString)
If string is not convertible to kind, returns LAST_KIND.
void LoadItems(const QJsonArray &)
11
Definition: header.h:171
const int sub
Definition: CraftManager.h:33
bool ItemsLess(const CraftItem *item1, const CraftItem *item2)
CraftItem * at(int item_position) const
bool Craft(CraftList *items, int sub) const
const int num
Definition: CraftManager.h:31
This class represents craft recipe.
Definition: CraftManager.h:43
const CraftManager * craft_manager
static constexpr int MakeId(const int kind, const int sub)
Definition: BlockManager.h:72
void Sort()
void clear()