freg  0.3
Free-Roaming Elementary Game
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
BlockManager.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 <QDataStream>
21 #include "BlockManager.h"
22 
23 #include "blocks/blocks.h"
24 #include "blocks/Dwarf.h"
25 #include "blocks/Bucket.h"
26 #include "blocks/Weapons.h"
27 #include "blocks/Illuminator.h"
28 #include "blocks/Containers.h"
29 #include "blocks/RainMachine.h"
30 #include "blocks/Armour.h"
31 #include "blocks/Filter.h"
32 
33 /** \page kinds List of available kinds
34  * Complete list.
35  * These kinds can be used as parameters to `get KIND SUB` command.
36  * \snippet BlockManager.cpp List of kinds */
37 const QByteArray BlockManager::kinds[] = { // do not use space, use '_'
38  /// [List of kinds]
39  "block",
40  "bell",
41  "container",
42  "intellectual",
43  "pick",
44  "liquid",
45  "grass",
46  "bush",
47  "rabbit",
48  "falling",
49  "clock",
50  "plate",
51  "workbench",
52  "weapon",
53  "ladder",
54  "door",
55  "box",
56  "text",
57  "map",
58  "predator",
59  "bucket",
60  "shovel",
61  "axe",
62  "hammer",
63  "illuminator",
64  "rain_machine",
65  "converter",
66  "armour",
67  "helmet",
68  "boots",
69  "telegraph",
70  "medkit",
71  "filter",
72  "informer",
73  /// [List of kinds]
74 };
75 
76 /** \page subs List of available substances
77  * Complete list.
78  * These substances can be used as parameters to `get KIND SUB` command.
79  * \snippet BlockManager.cpp List of subs */
80 const QByteArray BlockManager::subs[] = { // do not usp space, use '_'
81  /// [List of subs]
82  "stone",
83  "moss stone",
84  "nullstone",
85  "sky",
86  "star",
87  "diamond",
88  "soil",
89  "meat_of_intellectual",
90  "animal_meat",
91  "glass",
92  "wood",
93  "different",
94  "iron",
95  "water",
96  "greenery",
97  "sand",
98  "nut",
99  "rose",
100  "clay",
101  "air",
102  "paper",
103  "gold",
104  "bone",
105  "steel",
106  "adamantine",
107  "fire",
108  "coal",
109  "explosive",
110  "acid",
111  "cloud",
112  "dust",
113  "plastic",
114  /// [List of subs]
115 };
116 
118 
120  for (int sub=0; sub<LAST_SUB; ++sub) {
121  normals[sub] = new Block(BLOCK, sub);
122  }
123  static_assert((sizeof_array(BlockManager::kinds) == LAST_KIND),
124  "invalid number of strings in BlockManager::kinds[]");
125  static_assert((sizeof_array(BlockManager::subs) == LAST_SUB),
126  "invalid number of strings in BlockManager::subs[]");
127  static_assert((LAST_SUB <= 64 ), "too many substances, should be < 64.");
128  static_assert((LAST_KIND <= 128), "too many kinds, should be < 128.");
129  /*int sum = 0;
130  for (int kind = 0; kind<LAST_KIND; ++kind)
131  for (int sub = 0; sub <LAST_SUB; ++sub) {
132  sum += IsValid(kind, sub);
133  }
134  qDebug() << "valid pairs:" << sum;*/
135 }
136 
138  for(int sub=0; sub<LAST_SUB; ++sub) {
139  delete normals[sub];
140  }
141 }
142 
143 Block * BlockManager::Normal(const int sub) const { return normals[sub]; }
144 
145 Block * BlockManager::NewBlock(const int kind, const int sub) {
146  //qDebug("kind: %d, sub: %d, valid: %d", kind, sub, IsValid(kind, sub));
147  switch ( static_cast<enum kinds>(kind) ) {
148  case BLOCK: return new Block (kind, sub);
149  case BELL: return new Bell (kind, sub);
150  case CONTAINER: return new Container(kind, sub);
151  case DWARF: return new Dwarf (kind, sub);
152  case PICK: return new Pick (kind, sub);
153  case LIQUID: return new Liquid(kind, sub);
154  case GRASS: return new Grass (kind, sub);
155  case BUSH: return new Bush (kind, sub);
156  case RABBIT: return new Rabbit(kind, sub);
157  case FALLING: return new Falling(kind, sub);
158  case CLOCK: return new Clock (kind, sub);
159  case PLATE: return new Plate (kind, sub);
160  case WORKBENCH: return new Workbench(kind, sub);
161  case WEAPON: return new Weapon(kind, sub);
162  case LADDER: return new Ladder(kind, sub);
163  case DOOR: return new Door (kind, sub);
164  case BOX: return new Box (kind, sub);
165  case KIND_TEXT: return new Text (kind, sub);
166  case MAP: return new Map (kind, sub);
167  case PREDATOR: return new Predator(kind, sub);
168  case BUCKET: return new Bucket(kind, sub);
169  case SHOVEL: return new Shovel(kind, sub);
170  case AXE: return new Axe (kind, sub);
171  case HAMMER: return new Hammer(kind, sub);
172  case ILLUMINATOR: return new Illuminator(kind, sub);
173  case RAIN_MACHINE: return new RainMachine(kind, sub);
174  case CONVERTER: return new Converter(kind, sub);
175  case ARMOUR: return new Armour(kind, sub);
176  case HELMET: return new Helmet(kind, sub);
177  case BOOTS: return new Boots (kind, sub);
178  case TELEGRAPH: return new Telegraph(kind, sub);
179  case MEDKIT: return new MedKit(kind, sub);
180  case FILTER: return new Filter(kind, sub);
181  case INFORMER: return new Informer(kind, sub);
182  case LAST_KIND: break;
183  }
184  Q_UNREACHABLE();
185  return nullptr;
186 } // Block * BlockManager::NewBlock(int kind, int sub)
187 
188 Block * BlockManager::BlockFromFile(QDataStream & str,
189  const int kind, const int sub)
190 {
191  //qDebug("kind: %d, sub: %d, valid: %d", kind, sub, IsValid(kind, sub));
192  switch ( static_cast<enum kinds>(kind) ) {
193  case BLOCK: return new Block (str, kind, sub);
194  case BELL: return new Bell (str, kind, sub);
195  case CONTAINER: return new Container(str, kind, sub);
196  case DWARF: return new Dwarf (str, kind, sub);
197  case PICK: return new Pick (str, kind, sub);
198  case LIQUID: return new Liquid(str, kind, sub);
199  case GRASS: return new Grass (str, kind, sub);
200  case BUSH: return new Bush (str, kind, sub);
201  case RABBIT: return new Rabbit(str, kind, sub);
202  case FALLING: return new Falling(str, kind, sub);
203  case CLOCK: return new Clock (str, kind, sub);
204  case PLATE: return new Plate (str, kind, sub);
205  case WORKBENCH: return new Workbench(str, kind, sub);
206  case WEAPON: return new Weapon(str, kind, sub);
207  case LADDER: return new Ladder(str, kind, sub);
208  case DOOR: return new Door (str, kind, sub);
209  case BOX: return new Box (str, kind, sub);
210  case KIND_TEXT: return new Text (str, kind, sub);
211  case MAP: return new Map (str, kind, sub);
212  case PREDATOR: return new Predator(str, kind, sub);
213  case BUCKET: return new Bucket(str, kind, sub);
214  case SHOVEL: return new Shovel(str, kind, sub);
215  case AXE: return new Axe (str, kind, sub);
216  case HAMMER: return new Hammer(str, kind, sub);
217  case ILLUMINATOR: return new Illuminator(str, kind, sub);
218  case RAIN_MACHINE: return new RainMachine(str, kind, sub);
219  case CONVERTER: return new Converter(str, kind, sub);
220  case ARMOUR: return new Armour(str, kind, sub);
221  case HELMET: return new Helmet(str, kind, sub);
222  case BOOTS: return new Boots (str, kind, sub);
223  case TELEGRAPH: return new Telegraph(str, kind, sub);
224  case MEDKIT: return new MedKit(str, kind, sub);
225  case FILTER: return new Filter(str, kind, sub);
226  case INFORMER: return new Informer(str, kind, sub);
227  case LAST_KIND: break;
228  }
229  Q_UNREACHABLE();
230  return nullptr;
231 }
232 
233 bool BlockManager::KindSubFromFile(QDataStream & str,
234  quint8 * kind, quint8 * sub)
235 {
236  str >> *sub;
237  if ( *sub & 0x80 ) { // normal bit
238  *sub &= 0x7F;
239  return true;
240  } else {
241  *sub &= 0x7F;
242  str >> *kind;
243  return false;
244  }
245 }
246 
247 void BlockManager::DeleteBlock(Block * const block) const {
248  if ( block != Normal(block->Sub()) ) {
249  Active * const active = block->ActiveBlock();
250  if ( active != nullptr ) {
251  active->Unregister();
252  }
253  delete block;
254  }
255 }
256 
257 QString BlockManager::KindToString(const int kind) { return kinds[kind]; }
258 QString BlockManager:: SubToString(const int sub ) { return subs[sub ]; }
259 
260 int BlockManager::StringToKind(const QString str) {
261  int i = 0;
262  for ( ; i<LAST_KIND && kinds[i]!=str; ++i);
263  return i;
264 }
265 
266 int BlockManager::StringToSub(const QString str) {
267  int i = 0;
268  for ( ; i<LAST_SUB && subs[i]!=str; ++i);
269  return i;
270 }
271 
273  Block * const normal = Normal(block->Sub());
274  if ( block!=normal && *block==*normal ) {
275  delete block;
276  return normal;
277  } else {
278  return block;
279  }
280 }
281 
282 int BlockManager::KindFromId(const int id) { return (id >> 8); }
283 int BlockManager:: SubFromId(const int id) { return (id & 0xFF); }
284 
285 bool BlockManager::IsValid(const int kind, const int sub) {
286  const sub_groups group = Block::GetSubGroup(sub);
287  switch ( static_cast<enum kinds>(kind) ) {
288  case BLOCK: return true;
289  case LAST_KIND: break;
290  case DWARF: return ( sub == DIFFERENT || sub == H_MEAT
291  || group == GROUP_METAL );
292  case GRASS: return ( sub == GREENERY || sub == FIRE );
293  case BUSH: return ( sub == GREENERY || sub == WOOD );
294  case FALLING: return ( sub == WATER || sub == STONE || sub == SUB_DUST );
295  case LIQUID: return ( group == GROUP_MEAT || group == GROUP_METAL
296  || sub == STONE || sub == WATER );
297 
298  case BUCKET:
299  case CLOCK:
300  case RAIN_MACHINE:
301  case ARMOUR:
302  case HELMET:
303  case BOOTS:
304  case TELEGRAPH:
305  case MEDKIT:
306  case FILTER:
307  case INFORMER:
308  case BELL: return ( group == GROUP_METAL );
309 
310  case BOX:
311  case DOOR:
312  case LADDER:
313  case PLATE:
314  case WEAPON:
315  case PICK:
316  case SHOVEL:
317  case AXE:
318  case HAMMER:
319  case ILLUMINATOR:
320  case WORKBENCH:
321  case CONVERTER: return ( group == GROUP_METAL || group == GROUP_HANDY );
322  case CONTAINER: return ( group == GROUP_METAL ||
323  group == GROUP_HANDY ||
324  group == GROUP_MEAT );
325 
326  case PREDATOR:
327  case RABBIT: return ( sub == A_MEAT );
328 
329  case MAP:
330  case KIND_TEXT: return ( sub == PAPER || sub == GLASS );
331  }
332  Q_UNREACHABLE();
333  return false;
334 }
Definition: Weapons.h:43
static int StringToSub(QString)
If string is not convertible to substance, returns LAST_SUB.
Definition: blocks.h:199
20
Definition: header.h:135
10
Definition: header.h:170
void DeleteBlock(Block *) const
Does not actually delete normal blocks.
Definition: blocks.h:147
Container is multi-purpose container for blocks.
Definition: Containers.h:28
32
Definition: header.h:147
BlockManager block_manager
static int KindFromId(int id)
6
Definition: header.h:121
31
Definition: header.h:146
Block * normals[LAST_SUB]
Definition: BlockManager.h:85
Block * Normal(int sub) const
Use this to receive a pointer to normal block.
sub_groups
Definition: Block.h:76
29
Definition: header.h:144
Definition: Armour.h:25
Definition: blocks.h:35
0
Definition: header.h:115
Nothing is made from LAST_SUB.
Definition: header.h:193
The Informer class, provides various information.
Definition: blocks.h:244
Definition: Filter.h:25
static QString SubToString(int sub)
If substance is unknown, returns "unknown_sub".
static sub_groups GetSubGroup(int sub)
Definition: Block.cpp:275
This class is used for creating and deleting blocks, also for loading them from file.
Definition: BlockManager.h:43
21
Definition: header.h:136
static const QByteArray kinds[]
Definition: BlockManager.h:86
27
Definition: header.h:142
Block * ReplaceWithNormal(Block *block) const
For memory economy.
11
Definition: header.h:126
1
Definition: header.h:116
7 (hominid meat)
Definition: header.h:167
28
Definition: header.h:143
Definition: blocks.h:46
Definition: blocks.h:125
7
Definition: header.h:122
Definition: blocks.h:86
12
Definition: header.h:127
9
Definition: header.h:124
9
Definition: header.h:169
Definition: Bucket.h:26
static int StringToKind(QString)
If string is not convertible to kind, returns LAST_KIND.
11
Definition: header.h:171
20
Definition: header.h:180
static int SubFromId(int id)
Workbench allows craft from multiple sources. There can be up to 2 products. Also can be used as cont...
Definition: Containers.h:83
18
Definition: header.h:133
Definition: Armour.h:41
static bool IsValid(int kind, int sub)
26
Definition: header.h:141
14
Definition: header.h:129
kinds
Kinds of atom.
Definition: header.h:112
int Sub() const
Definition: Block.h:144
2
Definition: header.h:117
#define sizeof_array(ARRAY)
Definition: header.h:224
Definition: blocks.h:179
4
Definition: header.h:119
Definition: blocks.h:67
subs
Substance block is made from.
Definition: header.h:157
13
Definition: header.h:128
8
Definition: header.h:123
static Block * NewBlock(int kind, int sub)
Use this to receive a pointer to new not-normal block.
Box represents falling inventory.
Definition: Containers.h:56
Nothing is LAST_KIND.
Definition: header.h:150
19
Definition: header.h:134
static QString KindToString(int kind)
If kind is unknown, returns "unknown_kind".
22
Definition: header.h:137
Definition: Active.h:46
13
Definition: header.h:173
25
Definition: header.h:185
virtual Active * ActiveBlock()
Definition: Block.cpp:226
0
Definition: header.h:160
static const QByteArray subs[]
Definition: BlockManager.h:87
Definition: Weapons.h:67
23
Definition: header.h:138
Definition: Armour.h:34
16
Definition: header.h:131
Definition: blocks.h:26
Definition: blocks.h:232
Definition: Dwarf.h:28
17
Definition: header.h:132
10
Definition: header.h:125
Definition: Weapons.h:59
15
Definition: header.h:130
Weapon class represents simple weapons as sticks, pebbles and so on. Also is used as base class for m...
Definition: Weapons.h:25
3
Definition: header.h:118
5
Definition: header.h:120
void Unregister()
Definition: Active.cpp:79
Definition: Weapons.h:51
static Block * BlockFromFile(QDataStream &, int kind, int sub)
Use this to load block from file.
Block without special physics and attributes.
Definition: Block.h:89
Definition: blocks.h:109
30
Definition: header.h:145
8 (animal meat)
Definition: header.h:168
30
Definition: header.h:190
14
Definition: header.h:174
Definition: blocks.h:170
static bool KindSubFromFile(QDataStream &, quint8 *kind, quint8 *sub)
Returns true if block is normal.