Exemple #1
0
void Shred::Pyramid() {
    const int level = qMin(FlatUndeground(), HEIGHT-1-16);
    Block * const stone = Normal(STONE);
    for (int z=level+1, dz=0; dz<SHRED_WIDTH/2; z+=2, ++dz) { // pyramid
        for (int x=dz, y=dz; x<(SHRED_WIDTH - dz); ++x, ++y) {
            blocks[x][dz][z] =
                blocks[x][SHRED_WIDTH-1-dz][z  ] =
                blocks[x][              dz][z+1] =
                blocks[x][SHRED_WIDTH-1-dz][z+1] =
            blocks[dz][y][z] =
                blocks[SHRED_WIDTH-1-dz][y][z  ] =
                blocks[              dz][y][z+1] =
                blocks[SHRED_WIDTH-1-dz][y][z+1] = stone;
        }
    }
    Block * const air = Normal(AIR);
    PutBlock(air, SHRED_WIDTH/2, 0, level+1); // entrance
    // room below
    NormalCube(1, 1, HEIGHT/2-60, SHRED_WIDTH-2, SHRED_WIDTH-2, 8, AIR);
    for (int z=HEIGHT/2-52; z<=level; ++z) { // horizontal tunnel
        PutBlock(air, SHRED_WIDTH/2, SHRED_WIDTH/2, z);
    }
    SetNewBlock(CONTAINER, STONE, SHRED_WIDTH-2, SHRED_WIDTH-2, level+1);
    Inventory * const inv =
        GetBlock(SHRED_WIDTH-2,SHRED_WIDTH-2, level+1)->HasInventory();
    inv->Get(Normal(GOLD));
    SetNewBlock(PREDATOR, A_MEAT, SHRED_WIDTH-3, SHRED_WIDTH-2, level+1);
}
Exemple #2
0
void World::NoCheckMove(const ushort x, const ushort y, const ushort z,
		const ushort newx, const ushort newy, const ushort newz,
		const quint8 dir)
{
	Block * const block = GetBlock(x, y, z);
	Block * const block_to = GetBlock(newx, newy, newz);

	PutBlock(block_to, x, y, z);
	PutBlock(block, newx, newy, newz);

	if ( block_to->Transparent() != block->Transparent() ) {
		ReEnlighten(newx, newy, newz);
		ReEnlighten(x, y, z);
	}

	block_to->Move( Anti(dir) );
	block->Move(dir);

	Shred * shred = GetShred(x, y);
	shred->AddFalling(Shred::CoordInShred(x), Shred::CoordInShred(y), z+1);
	shred->AddFalling(Shred::CoordInShred(x), Shred::CoordInShred(y), z);
	shred = GetShred(newx, newy);
	shred->AddFalling(Shred::CoordInShred(newx), Shred::CoordInShred(newy),
		newz+1);
	shred->AddFalling(Shred::CoordInShred(newx), Shred::CoordInShred(newy),
		newz);
}
Exemple #3
0
bool Shred::LoadShred() {
    const QByteArray * const data =
        GetWorld()->GetShredData(longitude, latitude);
    if ( data == nullptr ) return false;
    QDataStream in(*data);
    quint8 read;
    in >>  read;
    if ( Q_UNLIKELY(CURRENT_SHRED_FORMAT_VERSION != read) ) {
        fprintf(stderr,
            "%s: Shred format: %d (must be %d). Generating new shred.\n",
            Q_FUNC_INFO, read, CURRENT_SHRED_FORMAT_VERSION);
        return false;
    } // else:
    in.setVersion(DATASTREAM_VERSION);
    in >> read;
    type = static_cast<shred_type>(read);
    in >> read;
    weather = static_cast<weathers>(read);
    Block * const null_stone = block_manager.Normal(NULLSTONE);
    Block * const air        = block_manager.Normal(AIR);
    SetAllLightMapNull();
    for (int x=0; x<SHRED_WIDTH; ++x)
    for (int y=0; y<SHRED_WIDTH; ++y) {
        PutBlock(null_stone, x, y, 0);
        for (int z=1; ; ++z) {
            quint8 kind, sub;
            if ( BlockManager::KindSubFromFile(in, &kind, &sub) ) { // normal
                if ( sub==SKY || sub==STAR ) {
                    while (z < HEIGHT-1) {
                        PutBlock(air, x, y, z++);
                    }
                    PutBlock(Normal(sub), x, y, HEIGHT-1);
                    break;
                } else {
                    PutBlock(Normal(sub), x, y, z);
                }
            } else {
                Active * const active = (blocks[x][y][z] =
                    BlockManager::BlockFromFile(in, kind, sub))->ActiveBlock();
                if ( active != nullptr ) {
                    active->SetXyz(x, y, z);
                    RegisterInit(active);
                    Falling * const falling = active->ShouldFall();
                    if ( falling != nullptr && falling->IsFalling() ) {
                        fallList.append(falling);
                    }
                }
            }
        }
    }
    return true;
} // bool Shred::LoadShred()
Exemple #4
0
Shred::Shred(const int shred_x, const int shred_y,
        const long longi, const long lati)
    :
        longitude(longi), latitude(lati),
        shredX(shred_x), shredY(shred_y),
        type(),
        activeListAll(),
        activeListFrequent(),
        shiningList(),
        fallList(),
        weather(WEATHER_CLEAR)
{
    if ( LoadShred() ) return; // successfull loading
    // new shred generation:
    Block * const null_stone = Normal(NULLSTONE);
    Block * const air  = Normal(AIR);
    Block * const sky  = Normal(SKY);
    Block * const star = Normal(STAR);
    SetAllLightMapNull();
    for (int i=0; i<SHRED_WIDTH; ++i)
    for (int j=0; j<SHRED_WIDTH; ++j) {
        PutBlock(null_stone, i, j, 0);
        for (int k=1; k<HEIGHT-1; ++k) {
            PutBlock(air, i, j, k);
        }
        PutBlock(((qrand()%5) ? sky : star), i, j, HEIGHT-1);
    }
    switch ( type = static_cast<shred_type>
            (GetWorld()->GetMap()->TypeOfShred(longi, lati)) )
    {
    case SHRED_WASTE:     WasteShred(); break;
    case SHRED_WATER:     Water();      break;
    case SHRED_PLAIN:     Plain();      break;
    case SHRED_MOUNTAIN:  Mountain();   break;
    case SHRED_DESERT:    Desert();     break;
    case SHRED_HILL:      Hill(false);  break;
    case SHRED_DEAD_HILL: Hill(true);   break;
    case SHRED_FOREST:      Forest(false); break;
    case SHRED_DEAD_FOREST: Forest(true);  break;
    case SHRED_NULLMOUNTAIN: NullMountain(); break;
    case SHRED_TESTSHRED: TestShred();  break;
    case SHRED_PYRAMID:   Pyramid();    break;
    case SHRED_CASTLE:    Castle();     break;
    case SHRED_CHAOS:     ChaosShred(); break;
    case SHRED_EMPTY: break;
    case SHRED_ACID_LAKE: Water(ACID ); break;
    case SHRED_LAVA_LAKE: Water(STONE); break;
    case SHRED_CRATER:    Water(AIR);   break;
    case SHRED_NORMAL_UNDERGROUND: NormalUnderground(); break;
    }
} // Shred::Shred(int shred_x, shred_y, long longi, lati, Shred * mem)
Exemple #5
0
bool Shred::Tree(const int x, const int y, const int z, const int height) {
    if ( not InBounds(x+2, y+2, height+z) ) return false;
    // check for room
    for (int i=x; i<=x+2; ++i)
    for (int j=y; j<=y+2; ++j)
    for (int k=z; k<z+height; ++k) {
        if ( AIR != GetBlock(i, j, k)->Sub() ) {
            return false;
        }
    }
    const int leaves_level = z+height/2;
    Block * const leaves = Normal(GREENERY);
    for (int i=x; i<=x+2; ++i)
    for (int j=y; j<=y+2; ++j) {
        for (int k=leaves_level; k<z+height; ++k ) {
            PutBlock(leaves, i, j, k);
        }
    }
    for (int k=qMax(z-1, 1); k < z+height-1; ++k) { // trunk
        SetBlock(Normal(WOOD), x+1, y+1, k);
    }
    // branches
    const int r = qrand();
    if ( r & 0x1 ) SetNewBlock(BLOCK, WOOD, x,   y+1, leaves_level, WEST);
    if ( r & 0x2 ) SetNewBlock(BLOCK, WOOD, x+2, y+1, leaves_level, EAST);
    if ( r & 0x4 ) SetNewBlock(BLOCK, WOOD, x+1, y,   leaves_level, NORTH);
    if ( r & 0x8 ) SetNewBlock(BLOCK, WOOD, x+1, y+2, leaves_level, SOUTH);
    return true;
}
Exemple #6
0
void Shred::NullMountain() {
    NormalUnderground();
    const int border_level = HEIGHT/2-2;
    NormalCube(0,SHRED_WIDTH/2-1,1, SHRED_WIDTH,2,border_level, NULLSTONE);
    NormalCube(SHRED_WIDTH/2-1,0,1, 2,SHRED_WIDTH,border_level, NULLSTONE);
    Block * const null_stone = Normal(NULLSTONE);
    for (int i=0; i<SHRED_WIDTH; ++i)
    for (int j=0; j<SHRED_WIDTH; ++j) {
        for (int k=border_level; k < HEIGHT-2; ++k) {
            const int surface =
                HEIGHT/2 * (pow(1./(i-7.5), 2) * pow(1./(j-7.5), 2)+1);
            if ( HEIGHT/2+1 < surface && surface >= k ) {
                PutBlock(null_stone, i, j, k);
            }
        }
    }
    const WorldMap * const map = GetWorld()->GetMap();
    if ( SHRED_NULLMOUNTAIN == map->TypeOfShred(longitude-1, latitude) ) { //N
        NormalCube(7,0,HEIGHT/2, 2,SHRED_WIDTH/2-1,HEIGHT/2-2, NULLSTONE);
    }
    if ( SHRED_NULLMOUNTAIN == map->TypeOfShred(longitude+1, latitude) ) { //S
        NormalCube(7,SHRED_WIDTH/2+1,HEIGHT/2, 2,SHRED_WIDTH/2-1,HEIGHT/2-2,
            NULLSTONE);
    }
    if ( SHRED_NULLMOUNTAIN == map->TypeOfShred(longitude, latitude+1) ) { //E
        NormalCube(SHRED_WIDTH/2+1,7,HEIGHT/2, SHRED_WIDTH/2-1,2,HEIGHT/2-2,
            NULLSTONE);
    }
    if ( SHRED_NULLMOUNTAIN == map->TypeOfShred(longitude, latitude-1) ) { //W
        NormalCube(0,7,HEIGHT/2, SHRED_WIDTH/2-1,2,HEIGHT/2-2, NULLSTONE);
    }
}
Exemple #7
0
/*left,top:方块的左上角坐标,x,y:特殊方块的坐标 size:当前的子棋盘大小*/
void ChessBoard(int left,int top,int x,int y,int size)
{
    int i,t,s,pos;/*t是方块的编号,s是棋盘的一半尺寸!(size/2),pos表示方块位于哪一角 */
    if(size==1)
        return;
    t=tile++;/*当前L行方块的编号!递增*/
    s=size/2;

    /*------------处理左上角----------*/
    if(x<left+s && y<top+s)
    {
        ChessBoard(left,top,x,y,s);/*设置位于左上角的标识*/
        pos=1;
    }
    else
    {
        Board[left+s-1][top+s-1]=t;          /*不在左上角*/
        ChessBoard(left,top,left+s-1,top+s-1,s);
    }

    /*------------处理右上角----------*/
    if(x>=left+s && y<top+s)
    {
        ChessBoard(left+s,top,x,y,s);
        pos=2;
    }
    else
    {
        Board[left+s][top+s-1]=t;/*不在右上角*/
        ChessBoard(left+s,top,left+s,top+s-1,s);
    }

    /*------------处理左下角----------*/
    if(x<left+s && y>=top+s)
    {
        ChessBoard(left,top+s,x,y,s);
        pos=3;
    }
    else
    {
        Board[left+s-1][top+s]=t;
        ChessBoard(left,top+s,left+s-1,top+s-1,s);
    }

    /*------------处理右下角----------*/
    if(x>=left+s && y>=top+s)
    {
        ChessBoard(left+s,top+s,x,y,s);
        pos=4;
    }
    else
    {
        Board[left+s][top+s]=t;
        ChessBoard(left+s,top+s,left+s,top+s,s);
    }
    /*画出当前的L方块*/
    PutBlock(left+s,top+s,pos);
}
Exemple #8
0
void Shred::NormalCube(
        const int x_start, const int y_start, const int z_start,
        const int x_size,  const int y_size,  const int z_size, const subs sub)
{
    Block * const block = Normal(sub);
    for (int x=x_start; x < x_start+x_size; ++x)
    for (int y=y_start; y < y_start+y_size; ++y)
    for (int z=z_start; z < z_start+z_size; ++z) {
        if ( InBounds(x, y, z) ) {
            PutBlock(block, x, y, z);
        }
    }
}
Exemple #9
0
bool World::CanMove(const ushort x, const ushort y, const ushort z,
		const ushort newx, const ushort newy, const ushort newz,
		const quint8 dir)
{
	if ( !InBounds(x, y, z) ) {
		return false;
	}
	Block * const block = GetBlock(x, y, z);
	if ( NOT_MOVABLE == block->Movable() ) {
		return false;
	}
	Block * block_to = GetBlock(newx, newy, newz);
	if ( ENVIRONMENT == block->Movable() ) {
		if ( *block == *block_to ) {
			return false;
		} else if ( MOVABLE == block_to->Movable() ) {
			NoCheckMove(x, y, z, newx, newy, newz, dir);
			return true;
		}
	}
	switch ( block_to->BeforePush(dir, block) ) {
	case MOVE_SELF: block_to = GetBlock(newx, newy, newz); break;
	case DESTROY:
		DeleteBlock(block_to);
		PutBlock(Normal(AIR), newx, newy, newz);
		return true;
	break;
	case JUMP:
		if ( DOWN!=dir && UP!=dir ) {
			Jump(x, y, z, dir);
			return false;
		}
	break;
	case MOVE_UP:
		if ( DOWN!=dir && UP!=dir ) {
			Move(x, y, z, UP);
			return false;
		}
	break;
	case DAMAGE:
		Damage(x, y, z,
			block_to->DamageLevel(),
			block_to->DamageKind());
		return false;
	break;
	}
	return ( ENVIRONMENT==block_to->Movable() );/* ||
		( (block->Weight() > block_to->Weight()) &&
			Move(newx, newy, newz, dir) ) );*/
} // bool World::CanMove(ushort x, y, z, newx, newy, newz, quint8 dir)
Exemple #10
0
void World::DestroyAndReplace(const ushort x, const ushort y, const ushort z) {
	Block * const temp = GetBlock(x, y, z);
	if ( temp->Durability() > 0 ) {
		return;
	}
	Block * const dropped = temp->DropAfterDamage();
	Shred * const shred = GetShred(x, y);
	const ushort x_in_shred = Shred::CoordInShred(x);
	const ushort y_in_shred = Shred::CoordInShred(y);
	if ( PILE!=temp->Kind() && (temp->HasInventory() || dropped) ) {
		Block * const new_pile=( ( dropped && PILE==dropped->Kind() ) ?
			dropped : NewBlock(PILE, DIFFERENT) );
		shred->SetBlock(new_pile, x_in_shred, y_in_shred, z);
		Inventory * const inv = temp->HasInventory();
		Inventory * const new_pile_inv = new_pile->HasInventory();
		if ( inv ) {
			new_pile_inv->GetAll(inv);
		}
		if ( dropped && PILE!=dropped->Kind() &&
				!new_pile_inv->Get(dropped) )
		{
			DeleteBlock(dropped);
		}
		shred->AddFalling(x_in_shred, y_in_shred, z);
	} else {
		PutBlock(Normal(AIR), x, y, z);
	}
	const int old_transparency = temp->Transparent();
	const uchar old_light = temp->LightRadius();
	DeleteBlock(temp);
	shred->AddFalling(x_in_shred, y_in_shred, z+1);
	if ( old_transparency != INVISIBLE ) {
		ReEnlightenBlockRemove(x, y, z);
	}
	if ( old_light ) {
		RemoveFireLight(x, y, z);
	}
} // void World::DestroyAndReplace(ushort x, y, z)
Exemple #11
0
void World::PhysEvents() {
	const QWriteLocker writeLock(rwLock);
	switch ( toResetDir ) {
	case UP: break; // no reset
	case DOWN: // full reset
		emit StartReloadAll();
		DeleteAllShreds();
		longitude = newLongi;
		latitude  = newLati;
		LoadAllShreds();
		emit NeedPlayer(newX, newY, newZ);
		emit UpdatedAll();
		emit FinishReloadAll();
		toResetDir = UP; // set no reset
	break;
	default:
		ReloadShreds(toResetDir);
		toResetDir = UP; // set no reset
	}

	static const ushort start = numShreds/2-numActiveShreds/2;
	static const ushort end   = start+numActiveShreds;
	for (ushort i=start; i<end; ++i)
	for (ushort j=start; j<end; ++j) {
		shreds[i+j*NumShreds()]->PhysEventsFrequent();
	}

	if ( TimeStepsInSec() > timeStep ) {
		++timeStep;
		for (ushort i=start; i<end; ++i)
		for (ushort j=start; j<end; ++j) {
			shreds[i+j*NumShreds()]->DeleteDestroyedActives();
		}
		return;
	} // else:

	for (ushort i=start; i<end; ++i)
	for (ushort j=start; j<end; ++j) {
		shreds[i+j*NumShreds()]->PhysEventsRare();
	}
	for (ushort i=start; i<end; ++i)
	for (ushort j=start; j<end; ++j) {
		shreds[i+j*NumShreds()]->DeleteDestroyedActives();
	}
	timeStep = 0;
	++time;
	// sun/moon moving
	if ( sun_moon_x != SunMoonX() ) {
		const ushort y = SHRED_WIDTH*numShreds/2;
		PutBlock(Normal(ifStar ? STAR : SKY), sun_moon_x, y, HEIGHT-1);
		emit Updated(sun_moon_x, y, HEIGHT-1);
		sun_moon_x = SunMoonX();
		ifStar = ( STAR==Sub(sun_moon_x, y, HEIGHT-1) );
		PutBlock(Normal(SUN_MOON), sun_moon_x, y, HEIGHT-1);
		emit Updated(sun_moon_x, y, HEIGHT-1);
	}
	switch ( TimeOfDay() ) {
	case END_OF_NIGHT:
		ReEnlightenTime();
		emit Notify(tr("It's morning now."));
	break;
	case END_OF_MORNING: emit Notify(tr("It's day now.")); break;
	case END_OF_NOON:    emit Notify(tr("It's evening now.")); break;
	case END_OF_EVENING:
		ReEnlightenTime();
		emit Notify(tr("It's night now."));
	break;
	}
	emit UpdatesEnded();
	// emit ExitReceived(); // close all after 1 turn
} // void World::PhysEvents()
Exemple #12
0
void World::MakeSun() {
	ifStar = ( STAR==Sub( (sun_moon_x=SunMoonX()), SHRED_WIDTH*numShreds/2,
		HEIGHT-1) );
	PutBlock(Normal(SUN_MOON),
		sun_moon_x, SHRED_WIDTH*numShreds/2, HEIGHT-1);
}