freg  0.3
Free-Roaming Elementary Game
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Containers.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 "blocks/Containers.h"
21 #include "World.h"
22 #include "Shred.h"
23 #include "BlockManager.h"
24 #include "CraftManager.h"
25 
26 const int CONVERTER_LIGHT_RADIUS = 2;
27 
28 // Container::
29  void Container::Damage(const int dmg, const int dmg_kind) {
30  if ( dmg_kind >= DAMAGE_PUSH_UP ) {
31  Push(X(), Y(), Z(), dmg_kind);
32  } else {
33  Block::Damage(dmg, dmg_kind);
34  }
35  }
36 
37  int Container::ShouldAct() const {
38  return ( Sub() == IRON || Sub() == WATER ) ?
40  }
41 
42  void Container::ReceiveSignal(QString) {}
43  Inventory * Container::HasInventory() { return this; }
47 
48  Block * Container::DropAfterDamage(bool * const delete_block) {
49  Block * const pile = BlockManager::NewBlock(BOX, DIFFERENT);
50  Inventory * const pile_inv = pile->HasInventory();
51  GetAll(pile_inv);
52  *delete_block = not pile_inv->Get(this);
53  return pile;
54  }
55 
56  int Container::Weight() const {
57  return Block::Weight()*4 + Inventory::Weight();
58  }
59 
60  QString Container::FullName() const {
61  switch ( Sub() ) {
62  case IRON: return tr("Locker");
63  case WATER: return tr("Fridge");
64  default: return tr("Chest (%1)").arg(SubName(Sub()));
65  }
66  }
67 
68  void Container::SaveAttributes(QDataStream & out) const {
71  }
72 
73  Container::Container(const int kind, const int sub, const int size) :
74  Active(kind, sub),
75  Inventory(size)
76  {}
77 
78  Container::Container(QDataStream & str, const int kind, const int sub,
79  const int size)
80  :
81  Active(str, kind, sub),
82  Inventory(str, size)
83  {}
84 
85 // Box::
86  Box::Box(const int kind, const int sub) :
87  Falling(kind, sub),
89  {}
90 
91  Box::Box(QDataStream & str, const int kind, const int sub) :
92  Falling(str, kind, sub),
93  Inventory(str, INV_SIZE)
94  {}
95 
96  void Box::SaveAttributes(QDataStream & str) const {
99  }
100 
101  int Box::ShouldAct() const { return FREQUENT_RARE; }
102  void Box::ReceiveSignal(const QString str) { Active::ReceiveSignal(str); }
103  Inventory * Box::HasInventory() { return this; }
105 
107  if ( GROUP_MEAT == GetSubGroup(Sub()) ) {
109  if ( GetDurability() <= 0 ) {
110  GetWorld()->DestroyAndReplace(X(), Y(), Z());
111  }
112  } else if ( Sub() == DIFFERENT ) {
113  Inventory * const inv =
114  GetWorld()->GetBlock(X(), Y(), Z()-1)->HasInventory();
115  if ( inv ) {
116  inv->GetAll(this);
117  }
118  if ( IsEmpty() ) {
119  GetWorld()->DestroyAndReplace(X(), Y(), Z());
120  }
121  }
122  }
123 
124  Block * Box::DropAfterDamage(bool * const delete_block) {
125  *delete_block = true;
126  return block_manager.Normal(AIR);
127  }
128 
129  void Box::Damage(const int dmg, const int dmg_kind) {
130  if ( dmg_kind >= DAMAGE_PUSH_UP ) {
131  Push(X(), Y(), Z(), dmg_kind);
132  if ( Sub()==DIFFERENT && IsEmpty() ) {
133  Break();
134  }
135  } else {
136  Block::Damage(dmg, dmg_kind);
137  }
138  }
139 
140  QString Box::FullName() const {
141  switch ( Sub() ) {
142  default: return tr("Box (%1)").arg(SubName(Sub()));
143  case H_MEAT:
144  case A_MEAT: return tr("Corpse (%1)").arg(SubName(Sub()));
145  case DIFFERENT: return tr("Pile");
146  }
147  }
148 
150  if ( GROUP_MEAT == GetSubGroup(Sub()) ) {
151  GetWorld()->DestroyAndReplace(X(), Y(), Z());
152  return USAGE_TYPE_NO;
153  } else {
154  return USAGE_TYPE_OPEN;
155  }
156  }
157 
158 // Workbench::
160  for (int i=0; i<Start(); ++i) { // remove previous products
161  while ( Number(i) ) {
162  Block * const to_pull = ShowBlock(i);
163  Pull(i);
164  block_manager.DeleteBlock(to_pull);
165  }
166  }
167  int materials_number = 0;
168  for (int i=Start(); i<Size(); ++i) {
169  if ( Number(i) ) {
170  ++materials_number;
171  }
172  }
173  CraftList list(materials_number);
174  for (int i=Start(); i<Size(); ++i) {
175  if ( Number(i) ) {
176  list << new CraftItem(
177  {Number(i), ShowBlock(i)->Kind(), ShowBlock(i)->Sub()} );
178  }
179  }
180  if ( craft_manager->Craft(&list, Sub()) ) {
181  for (int i=0; i<list.size(); ++i) {
182  for (int n=0; n<list.at(i)->num; ++n) {
183  const CraftItem * const item = list.at(i);
184  GetExact(BlockManager::NewBlock(item->kind, item->sub), i);
185  }
186  }
187  }
188  }
189 
190  bool Workbench::Drop(const int src, const int dest,
191  const int num, Inventory * const inv_to)
192  {
193  if ( inv_to == nullptr
194  || src >= Size()
195  || dest >= inv_to->Size()
196  || Number(src) == 0 )
197  {
198  return false;
199  }
200  for (int i=0; i<num; ++i) {
201  if ( not inv_to->Get(ShowBlock(src), dest) ) return false;
202  Pull(src);
203  if ( src < Start() ) {
204  // remove materials:
205  for (int i=Start(); i<Size(); ++i) {
206  while ( Number(i) ) {
207  Block * const to_pull = ShowBlock(i);
208  Pull(i);
209  block_manager.DeleteBlock(to_pull);
210  }
211  }
212  } else {
213  Craft();
214  }
215  }
216  return true;
217  }
218 
219  QString Workbench::FullName() const {
220  switch ( Sub() ) {
221  case WOOD: return tr("Workbench");
222  default: return tr("Anvil (%1)").arg(SubName(Sub()));
223  }
224  }
225 
226  QString Workbench::InvFullName(const int slot_number) const {
227  return ( Number(slot_number) > 0 ) ?
228  Inventory::InvFullName(slot_number) : ( slot_number < Start() ) ?
229  tr("-product-") : tr("-material-");
230  }
231 
232  int Workbench::Start() const { return 2; }
233 
234  bool Workbench::Get(Block * const block, const int start) {
235  if ( Inventory::Get(block, start) ) {
236  Craft();
237  return true;
238  } else {
239  return false;
240  }
241  }
242 
243  bool Workbench::GetAll(Inventory * const from) {
244  if ( Inventory::GetAll(from) ) {
245  Craft();
246  return true;
247  } else {
248  return false;
249  }
250  }
251 
252  Workbench::Workbench(const int kind, const int sub) :
253  Container(kind, sub, WORKBENCH_SIZE)
254  {}
255 
256  Workbench::Workbench(QDataStream & str, const int kind, const int sub) :
257  Container(str, kind, sub, WORKBENCH_SIZE)
258  {}
259 
260 // Converter
261  Converter::Converter(const int kind, const int sub) :
262  Container(kind, sub, WORKBENCH_SIZE),
263  isOn(false),
264  fuelLevel(0),
265  lightRadius(0),
266  damageKindOn(),
267  damageKindOff()
268  {
269  InitDamageKinds();
270  }
271 
272  Converter::Converter(QDataStream & str, const int kind, const int sub) :
273  Container(str, kind, sub, WORKBENCH_SIZE),
274  isOn(),
275  fuelLevel(),
276  lightRadius(),
277  damageKindOn(),
278  damageKindOff()
279  {
280  str >> isOn >> fuelLevel;
282  InitDamageKinds();
283  }
284 
285  void Converter::SaveAttributes(QDataStream & out) const {
287  out << isOn << fuelLevel;
288  }
289 
290  int Converter::ShouldAct() const { return FREQUENT_RARE; }
291  int Converter::LightRadius() const { return lightRadius; }
292 
293  QString Converter::InvFullName(const int slot_number) const {
294  return ( Number(slot_number) == 0 ) ?
295  tr("-fuel-") : Inventory::InvFullName(slot_number);
296  }
297 
298  int Converter::DamageKind() const {
299  return (fuelLevel > 0) ? damageKindOn : 0;
300  }
301 
303  if ( isOn && fuelLevel < SECONDS_IN_DAY/DamageLevel() ) {
304  for (int i=Size()-1; i>=0; --i) {
305  Block * const block = ShowBlock(i);
306  if ( block != nullptr ) {
307  const int add = ConvertRatio(block->Sub());
308  if ( add > 0 ) {
309  fuelLevel += add;
310  Pull(i);
311  block_manager.DeleteBlock(block);
312  break;
313  }
314  }
315  }
316  }
317  World * const world = GetWorld();
318  if ( fuelLevel <= 0
319  || ( Sub() == STONE
320  && world->GetBlock(X(), Y(), Z()+1)->Sub() == WATER ) )
321  {
322  Damage(1, damageKindOff);
323  } else {
324  if (world->Damage(X(), Y(), Z()+1, DamageLevel(), damageKindOn)<=0)
325  {
326  world->DestroyAndReplace(X(), Y(), Z()+1);
327  }
328  fuelLevel -= DamageLevel();
329  }
330  }
331 
332  QString Converter::FullName() const {
333  QString name;
334  switch ( Sub() ) {
335  default:
336  case STONE: name = tr("Furnace"); break;
337  }
338  return name + tr(" (charge for %1 s)").arg(fuelLevel/DamageLevel());
339  }
340 
342  switch ( Sub() ) {
343  default:
344  qDebug("%s: sub ?: %d.", Q_FUNC_INFO, Sub());
345  // no break;
346  case STONE:
349  break;
350  }
351  }
352 
353  void Converter::Damage(const int dmg, const int dmg_kind) {
354  if ( dmg_kind == damageKindOn ) {
355  if ( not isOn ) {
356  isOn = true;
357  GetWorld()->GetShred(X(), Y())->AddShining(this);
358  GetWorld()->Shine(X(), Y(), Z(),
360  } else {
361  fuelLevel += dmg;
362  }
363  } else if ( dmg_kind == damageKindOff ) {
364  isOn = false;
365  fuelLevel = 0;
366  lightRadius = 0;
367  GetWorld()->GetShred(X(), Y())->RemShining(this);
368  } else {
369  Block::Damage(dmg, dmg_kind);
370  }
371  }
372 
373  int Converter::ConvertRatio(const int sub) const {
374  switch ( Sub() ) {
375  default: return 0;
376  case STONE: switch ( sub ) {
377  default: return 0;
378  case WOOD: return 50;
379  case GREENERY: return 10;
380  }
381  }
382  }
Inventory * HasInventory() overridefinal
Definition: Containers.cpp:43
int X() const
Definition: Active.cpp:158
usage_types Use(Block *who) override
Definition: Containers.cpp:149
const int MAX_DURABILITY
10 bits to store durability in file, signed.
Definition: World.h:43
QString FullName() const override
Definition: Containers.cpp:219
virtual void SaveAttributes(QDataStream &) const
Definition: Block.cpp:307
10
Definition: header.h:170
bool IsEmpty() const
Definition: Inventory.cpp:187
void DeleteBlock(Block *) const
Does not actually delete normal blocks.
Container is multi-purpose container for blocks.
Definition: Containers.h:28
BlockManager block_manager
push_reaction
Definition: header.h:95
static QString SubName(int sub)
Returns translated substance name.
Definition: Block.cpp:69
inner_actions ActInner() override
Definition: Containers.cpp:104
int Number(int i) const
Definition: Inventory.cpp:28
World * world
Definition: World.cpp:32
World provides global physics and shred connection.
Definition: World.h:52
virtual void Damage(int dmg, int dmg_kind)
Definition: Block.cpp:117
short Z() const
Definition: Xyz.cpp:30
void Damage(int dmg, int dmg_kind) override
Definition: Containers.cpp:353
Block * Normal(int sub) const
Use this to receive a pointer to normal block.
virtual int Weight() const
Definition: Block.cpp:242
bool GetAll(Inventory *from) override
Returns true on success.
Definition: Containers.cpp:243
void ReceiveSignal(QString) override
Definition: Containers.cpp:102
void DoRareAction() override
Definition: Containers.cpp:302
virtual bool Get(Block *block, int start=0)
Returns true on success.
Definition: Inventory.cpp:78
int ShouldAct() const override
Definition: Containers.cpp:37
QString InvFullName(int slot_number) const override
Definition: Containers.cpp:293
static sub_groups GetSubGroup(int sub)
Definition: Block.cpp:275
virtual Inventory * HasInventory()
Definition: Block.cpp:224
Block * DropAfterDamage(bool *delete_block) override
Should return dropped block.
Definition: Containers.cpp:48
int DamageKind() const override
Definition: Containers.cpp:298
Block * ShowBlock(int slot) const
Definition: Inventory.cpp:182
quint16 fuelLevel
Definition: Containers.h:126
int size() const
void ReceiveSignal(QString) override
Receive text signal.
Definition: Containers.cpp:42
const int kind
Definition: CraftManager.h:32
7 (hominid meat)
Definition: header.h:167
void RemShining(Active *)
Definition: Shred.cpp:291
5
Definition: Block.h:44
QString FullName() const override
Definition: Containers.cpp:60
int Size() const
Definition: Inventory.cpp:27
virtual bool GetAll(Inventory *from)
Returns true on success.
Definition: Inventory.cpp:49
int Start() const override
Definition: Containers.cpp:232
int Weight() const override
Definition: Containers.cpp:56
Container(int kind, int sub, int size=INV_SIZE)
Definition: Containers.cpp:73
void Shine(int x, int y, int z, int level)
If init is false, light will not spread from non-invisible blocks.
inner_actions
See Shred::PhysEventsRare() for details.
Definition: Active.h:36
void ReceiveSignal(QString) override
Receive text signal.
Definition: Active.cpp:156
11
Definition: header.h:171
int Y() const
Definition: Active.cpp:162
int ShouldAct() const override
Definition: Containers.cpp:101
push_reaction PushResult(dirs) const override
Definition: Containers.cpp:45
void Craft()
Definition: Containers.cpp:159
Block * GetBlock(int x, int y, int z) const
Definition: World.cpp:204
virtual int DamageLevel() const
Definition: Block.cpp:209
World * GetWorld() const
Definition: Active.cpp:140
const int sub
Definition: CraftManager.h:33
int LightRadius() const override
Definition: Containers.cpp:291
void InitDamageKinds()
Definition: Containers.cpp:341
damage_kinds damageKindOn
Definition: Containers.h:130
CraftItem * at(int item_position) const
int Kind() const
Definition: Block.h:145
int Sub() const
Definition: Block.h:144
void Damage(int dmg, int dmg_kind) override
Definition: Containers.cpp:129
12
Definition: header.h:172
virtual bool GetExact(Block *block, int num)
Returns true if block found its place.
Definition: Inventory.cpp:103
bool Drop(int src, int dest, int num, Inventory *inv) override
Returns true on success.
Definition: Containers.cpp:190
19
Definition: header.h:179
static Block * NewBlock(int kind, int sub)
Use this to receive a pointer to new not-normal block.
const int INV_SIZE
Definition: Inventory.h:28
void SaveAttributes(QDataStream &out) const override
Definition: Active.cpp:248
void DoRareAction() override
Definition: Containers.cpp:106
damage_kinds damageKindOff
Definition: Containers.h:131
Definition: Active.h:46
13
Definition: header.h:173
bool isOn
Definition: Containers.h:125
usage_types
Definition: header.h:196
virtual int Weight() const
Definition: Inventory.cpp:169
QString FullName() const override
Definition: Containers.cpp:332
void Damage(int dmg, int dmg_kind) override
Definition: Containers.cpp:29
void DestroyAndReplace(int x, int y, int z)
Does not check target block durability.
Definition: World.cpp:525
Workbench(int kind, int sub)
Definition: Containers.cpp:252
dirs
Definition: header.h:85
bool Craft(CraftList *items, int sub) const
void Push(int x, int y, int z, int push_direction)
Definition: Inventory.cpp:196
void Pull(int num)
Removes block from inventory. Does not delete block.
Definition: Inventory.cpp:59
void SaveAttributes(QDataStream &out) const override
Definition: Containers.cpp:96
bool Get(Block *block, int start) override
Returns true on success.
Definition: Containers.cpp:234
Provides block ability to contain other blocks inside.
Definition: Inventory.h:33
int ConvertRatio(int sub) const
Definition: Containers.cpp:373
0
Definition: header.h:160
Shred * GetShred(int i, int j) const
Definition: World.cpp:40
usage_types Use(Block *who) override
Definition: Containers.cpp:44
int Damage(int x, int y, int z, int level, int dmg_kind)
Returns damaged block result durability.
Definition: World.cpp:508
const int CONVERTER_LIGHT_RADIUS
Definition: Containers.cpp:26
Inventory * HasInventory() overridefinal
Definition: Containers.cpp:103
int GetDurability() const
Definition: Block.cpp:232
const int num
Definition: CraftManager.h:31
16
Definition: header.h:131
void Break()
Set durability to null.
Definition: Block.cpp:230
This class represents craft recipe.
Definition: CraftManager.h:43
QString FullName() const override
Definition: Containers.cpp:140
QString InvFullName(int slot_number) const override
Definition: Containers.cpp:226
Converter(int kind, int sub)
Definition: Containers.cpp:261
11
Definition: Block.h:50
void AddShining(Active *)
Definition: Shred.cpp:285
int lightRadius
Definition: Containers.h:129
const CraftManager * craft_manager
inner_actions ActInner() override
Definition: Containers.cpp:46
Block without special physics and attributes.
Definition: Block.h:89
Box(int kind, int sub)
Definition: Containers.cpp:86
8 (animal meat)
Definition: header.h:168
virtual QString InvFullName(int num) const
Definition: Inventory.cpp:145
virtual void SaveAttributes(QDataStream &out) const
Definition: Inventory.cpp:65
const int WORKBENCH_SIZE
Definition: Containers.h:26
14
Definition: header.h:174
void SaveAttributes(QDataStream &) const override
Definition: Containers.cpp:285
Block * DropAfterDamage(bool *delete_block) override
Should return dropped block.
Definition: Containers.cpp:124
int ShouldAct() const override
Definition: Containers.cpp:290
void SaveAttributes(QDataStream &out) const override
Definition: Containers.cpp:68