20 #include <QDataStream>
68 const QByteArray *
const data =
70 if ( data ==
nullptr )
return false;
71 QDataStream in(*data);
75 qDebug(
"%s: Shred format: %d (must be %d). Generating new shred.",
90 for (
int z=1; ; ++z) {
105 if ( active !=
nullptr ) {
109 if ( falling !=
nullptr && falling->
IsFalling() ) {
120 const long longi,
const long lati)
122 longitude(longi), latitude(lati),
123 shredX(shred_x), shredY(shred_y),
126 activeListFrequent(),
141 for (
int k=1; k<
HEIGHT-1; ++k) {
144 PutBlock(((qrand()%5) ? sky : star), i, j, HEIGHT-1);
146 switch (
type = static_cast<shred_type>
147 (
GetWorld()->GetMap()->TypeOfShred(longi, lati)) )
172 QByteArray *
const shred_data =
new QByteArray();
173 shred_data->reserve(30000);
174 QDataStream outstr(shred_data, QIODevice::WriteOnly);
182 for (
int z=1; z <= height; ++z) {
206 if ( *i ==
nullptr ) {
211 Block *
const floor_block =
GetBlock(x_in, y_in, (*i)->Z()-1);
212 if ( (*i)->Weight() <= 0
214 && floor_block->Sub() !=
AIR ) )
216 (*i)->SetFalling(
false);
218 }
else if ( not
world->
Move((*i)->X(), (*i)->Y(), (*i)->Z(),
DOWN) ) {
226 if ( *i !=
nullptr ) {
234 if ( *i !=
nullptr ) {
235 switch ( (*i)->ActInner() ) {
251 const int should_act = active->
ShouldAct();
270 if ( falling !=
nullptr ) {
279 if ( falling !=
nullptr && not falling->
IsFalling() ) {
302 switch ( direction ) {
307 default: Q_UNREACHABLE();
break;
313 if ( to_delete != block ) {
323 const int x,
const int y,
const int z)
325 Active *
const active = (
blocks[x][y][z]=block )->ActiveBlock();
326 if ( active !=
nullptr ) {
333 const int x,
const int y,
const int z,
const int dir)
341 const long longi,
const long lati)
343 return QString(
"%1%2/%3-%4.fm").
344 arg(
home_path).arg(world_name).arg(longi).arg(lati);
424 if ( set[i][j].kind == 0 && set[i][j].sub == 0)
continue;
425 SetNewBlock(set[i][j].kind, set[i][j].sub, j, i*2, level);
431 const int border_level =
HEIGHT/2-2;
437 for (
int k=border_level; k <
HEIGHT-2; ++k) {
439 HEIGHT/2 * (pow(1./(i-7.5), 2) * pow(1./(j-7.5), 2)+1);
440 if ( HEIGHT/2+1 < surface && surface >= k ) {
465 for (
int z=level+1, dz=0; dz<
SHRED_WIDTH/2; z+=2, ++dz) {
466 for (
int x=dz, y=dz; x<(
SHRED_WIDTH - dz); ++x, ++y) {
481 for (
int z=
HEIGHT/2-52; z<=level; ++z) {
493 const int bottom_level =
HEIGHT/2 - 1;
498 int level = bottom_level;
505 for (
int y=2; y<=3; ++y) {
506 for (
int step=0; step<5; ++step) {
510 if ( floors == 1 )
return;
513 || level == bottom_level )
518 || level == bottom_level )
523 || level == bottom_level )
528 || level == bottom_level )
532 if ( level == bottom_level + 5 ) {
542 for (
int k=1; k<
HEIGHT/2; ++k) {
550 const int x_start,
const int y_start,
const int z_start,
551 const int x_size,
const int y_size,
const int z_size,
const subs sub)
554 for (
int x=x_start; x < x_start+x_size; ++x)
555 for (
int y=y_start; y < y_start+y_size; ++y)
556 for (
int z=z_start; z < z_start+z_size; ++z) {
563 bool Shred::Tree(
const int x,
const int y,
const int z,
const int height) {
564 if ( not
InBounds(x+2, y+2, height+z) )
return false;
566 for (
int i=x; i<=x+2; ++i)
567 for (
int j=y; j<=y+2; ++j)
568 for (
int k=z; k<z+height; ++k) {
573 const int leaves_level = z+height/2;
575 for (
int i=x; i<=x+2; ++i)
576 for (
int j=y; j<=y+2; ++j) {
577 for (
int k=leaves_level; k<z+height; ++k ) {
581 for (
int k=qMax(z-1, 1); k < z+height-1; ++k) {
585 const int r = qrand();
622 const int CLOUD_HEIGHT =
HEIGHT*3/4;
626 const int to_replace_sub =
GetBlock(x, y, CLOUD_HEIGHT)->
Sub();
627 if ( to_replace_sub ==
AIR || to_replace_sub ==
SUB_CLOUD ) {
633 QFile file(QString(
"%1%2.room").
636 QString(
"-%1").arg(index) :
""));
637 if ( not file.open(QIODevice::ReadOnly | QIODevice::Text) )
return;
638 for (
int lines = 0; lines <
SHRED_WIDTH; ++lines) {
639 char buffer[SHRED_WIDTH + 1] = {0};
640 file.readLine(buffer,
sizeof(buffer));
641 for (
unsigned i=0; i<
sizeof(buffer); ++i) {
642 switch ( buffer[i] ) {
667 for (
int z=level; z<level+5; ++z) {
bool Move(int x, int y, int z, dirs dir)
Check and move.
const quint8 DATASTREAM_VERSION
static Block * Normal(int sub)
Puts block to coordinates, not activates it.
Shred(int shred_x, int shred_y, long longi, long lati)
QLinkedList< Active *const >::const_iterator ShiningEnd() const
void DropBlock(Block *bloc, bool on_water)
void NormalCube(int x_start, int y_start, int z_start, int x_size, int y_size, int z_size, subs)
static int CoordInShred(const int x)
Get local coordinate.
void SaveNormalToFile(QDataStream &out) const
long GlobalX(int x) const
Make global coordinate from local (in loaded zone).
long Latitude() const
Returns x (column) shred coordinate on world map.
void NormalUnderground(int depth=0, subs sub=SOIL)
void SetShredData(QByteArray *, long longi, long lati)
BlockManager block_manager
void PhysEventsFrequent()
const quint8 CURRENT_SHRED_FORMAT_VERSION
shred_type GetTypeOfShred() const
World provides global physics and shred connection.
QLinkedList< Active *const >::const_iterator ShiningBegin() const
void CoverWith(int kind, int sub)
void Water(subs sub=WATER)
QLinkedList< Active * > activeListFrequent
Block * Normal(int sub) const
Use this to receive a pointer to normal block.
void SetBlockNoCheck(Block *, int x, int y, int z)
Puts block to coordinates xyz and activates it.
QLinkedList< Falling * > fallList
static QString FileName(QString world_name, long longi, long lati)
virtual bool Get(Block *block, int start=0)
Returns true on success.
virtual Inventory * HasInventory()
void PutBlock(Block *const block, const int x, int y, int z)
void SetBlock(Block *block, int x, int y, int z)
Removes last block at xyz, then SetBlock, then makes block normal.
void LoadRoom(int level, int index=0)
void RemShining(Active *)
void SetXyz(short x, short y, short z)
Block * blocks[SHRED_WIDTH][SHRED_WIDTH][HEIGHT]
virtual int LightRadius() const
static bool InBounds(int x, int y, int z)
Lowest nullstone and sky are not in bounds.
virtual int ShouldAct() const
Provides declaration for class Inventory for freg.
virtual Falling * ShouldFall()
QLinkedList< Active *const > shiningList
int FlatUndeground(int depth=0)
void SetAllLightMapNull()
void Unregister(Active *)
static QString ShredTypeName(shred_type)
const WorldMap * GetMap() const
void RegisterInit(Active *)
void Rain(int kind, int sub)
static Block * NewBlock(int kind, int sub)
Use this to receive a pointer to new not-normal block.
long Longitude() const
Returns y (line) shred coordinate on world map.
void ChaosShred()
For testing purposes.
char TypeOfShred(long longi, long lati) const
virtual Active * ActiveBlock()
long GlobalY(int y) const
Provides block ability to contain other blocks inside.
Block * GetBlock(const int x, const int y, const int z) const
int CountShredTypeAround(int type) const
bool Tree(int x, int y, int z, int height)
Block combinations section (trees, buildings, etc):
void SaveToFile(QDataStream &out)
void SetFalling(bool set)
static int CoordOfShred(const int x)
Get shred coordinate in loaded zone (from 0 to numShreds).
void AddShining(Active *)
void RandomDrop(int num, int kind, int sub, bool on_water=false)
Puts num things(kind-sub) in random places on shred surface.
static Block * BlockFromFile(QDataStream &, int kind, int sub)
Use this to load block from file.
Block without special physics and attributes.
QLinkedList< Active * > activeListAll
Contains all active blocks.
void SetNewBlock(int kind, int sub, int x, int y, int z, int dir=UP)
QByteArray * GetShredData(long longi, long lati) const
static bool KindSubFromFile(QDataStream &, quint8 *kind, quint8 *sub)
Returns true if block is normal.
void Dew(int kind, int sub)