Пример #1
0
	bool ConvertItem(ReaderItem *Reader, WriterItem *Writer)
	{
		bool Status = false;

		if (Reader && Writer)
		{
			// convert object across
			if (Prog)
			{
				Prog->Value(Prog->Value() + Reader->Len);
				LgiYield();
			}

			Converted++;
			Status = true;

			// do children
			for (StorageItem *ri = Reader->Store->GetChild(); ri;
				ri = ri->GetNext())
			{
				ReaderItem *Reader1 = new ReaderItem(ri);
				if (Reader1 &&
					Reader1->Len > 0)
				{
					WriterItem *Writer2 = new WriterItem(Reader1);
					StorageItem *wi = Writer->Store->CreateSub(Writer2);
					if (Writer2 && wi)
					{
						wi->Object = Writer2;
						Writer2->Store = wi;

						Status &= ConvertItem(Reader1, Writer2);

						Writer2->Store->Object = 0;
						Writer2->Store = 0;
						DeleteObj(Writer2);
					}

					Reader1->Store->Object = 0;
					Reader1->Store = 0;
					DeleteObj(Reader1);
				}
			}
		}

		return Status;
	}
Пример #2
0
/**
* reads one 16x16 map block into stonesense tiles
* attempts to only read as much information as is necessary to do the tile optimization
*/
void readBlockToSegment(DFHack::Core& DF, WorldSegment& segment, 
    int BlockX, int BlockY, int BlockZ,
    uint32_t BoundrySX, uint32_t BoundrySY,
    uint32_t BoundryEX, uint32_t BoundryEY,
    vector< vector <int16_t> >* allLayers)
{
    if(ssConfig.skipMaps) {
        return;
    }
    //boundry check
    int blockDimX, blockDimY, blockDimZ;
    Maps::getSize((unsigned int &)blockDimX, (unsigned int &)blockDimY, (unsigned int &)blockDimZ);
    if( BlockX < 0 || BlockX >= blockDimX ||
        BlockY < 0 || BlockY >= blockDimY ||
        BlockZ < 0 || BlockZ >= blockDimZ ) {
            return;
    }

    //make boundries local
    BoundrySX -= BlockX * BLOCKEDGESIZE;
    BoundryEX -= BlockX * BLOCKEDGESIZE;
    BoundrySY -= BlockY * BLOCKEDGESIZE;
    BoundryEY -= BlockY * BLOCKEDGESIZE;

    //read block data
    df::map_block *trueBlock;
    trueBlock = Maps::getBlock(BlockX, BlockY, BlockZ);
    if(!trueBlock) {
        return;
    }        
    //read the map features
    t_feature local, global;
    Maps::ReadFeatures(BlockX,BlockY,BlockZ,&local,&global);
    //read local vein data
    vector <df::block_square_event_mineralst * > veins;
    vector <df::block_square_event_frozen_liquidst * > ices;
    vector <df::block_square_event_material_spatterst * > splatter;
    vector <df::block_square_event_grassst * > grass;
    vector <df::block_square_event_world_constructionst * > worldconstructions;
    Maps::SortBlockEvents(
        trueBlock,
        &veins,
        &ices,
        &splatter,
        &grass,
        &worldconstructions);    
    //parse block
    for(uint32_t ly = BoundrySY; ly <= BoundryEY; ly++) {
        for(uint32_t lx = BoundrySX; lx <= BoundryEX; lx++) {
            uint32_t gx = lx + (BlockX * BLOCKEDGESIZE);
            uint32_t gy = ly + (BlockY * BLOCKEDGESIZE);
            if( !segment.CoordinateInsideSegment( gx, gy, BlockZ) ) {
                continue;
            }

            bool shouldBeIncluded = true;

            //open terrain needs to be included to make blackboxes if 
            // we are shading but not showing hidden tiles
            if(isOpenTerrain(trueBlock->tiletype[lx][ly]) 
                && trueBlock->tiletype[lx][ly] != tiletype::RampTop) {
                    if(!ssConfig.show_hidden_tiles 
                        && ssConfig.shade_hidden_tiles 
                        && trueBlock->designation[lx][ly].bits.hidden) {
                            shouldBeIncluded = true;
                    } else {
                        shouldBeIncluded = false;
                    }
                    //all other terrain needs including, except for hidden tiles
                    // when we are neither showing nor shading hidden tiles
            } else if(!ssConfig.show_hidden_tiles
                && !ssConfig.shade_hidden_tiles
                && trueBlock->designation[lx][ly].bits.hidden) {
                    shouldBeIncluded = false;
            }

            //add back in any liquid tiles, in case they can be seen from above
            // as well as any hanging buildings
            if(trueBlock->designation[lx][ly].bits.flow_size
                || trueBlock->occupancy[lx][ly].bits.building) {
                    shouldBeIncluded = true;
            }

			//add back in any tiles that are constructions or designations
			if( ssConfig.show_designations
				&& containsDesignations(
					trueBlock->designation[lx][ly], 
					trueBlock->occupancy[lx][ly] ) ) {
				shouldBeIncluded = true;
			}

            if(!shouldBeIncluded){
                continue;
            }

            Tile * b = segment.ResetTile(gx, gy, BlockZ, trueBlock->tiletype[lx][ly]);
			
			b->occ.bits.unit = false;//this will be set manually when we read the creatures vector
            b->occ = trueBlock->occupancy[lx][ly];
			b->designation = trueBlock->designation[lx][ly];

			//if the tile has designations, read them and nothing else
			if( ssConfig.show_designations 
				&& readDesignationsToTile( 
					b, trueBlock->designation[lx][ly], 
					trueBlock->occupancy[lx][ly] ) ) {
						continue;
			}
			
			//set whether the tile is hidden
			b->fog_of_war = !b->designation.bits.pile;

            //don't read detailed information for blackbox tiles
            if(!ssConfig.show_hidden_tiles
                && ssConfig.shade_hidden_tiles
                && b->designation.bits.hidden
                && !b->designation.bits.flow_size) {
                    continue;
            }

            //read the grasses
            b->grasslevel = 0;
            b->grassmat = -1;
            //b->grasslevels.clear();
            //b->grassmats.clear();
            for(int i = 0; i < grass.size(); i++) {
                if(grass[i]->amount[lx][ly] > 0 && b->grasslevel == 0) { //b->grasslevel)
                    b->grasslevel = grass[i]->amount[lx][ly];
                    b->grassmat = grass[i]->plant_index;
                    //b->grasslevels.push_back(grass[i].intensity[lx][ly]);
                    //b->grassmats.push_back(grass[i].material);
                }
            }

			//read the water flows and direction.
			b->flow_direction = trueBlock->liquid_flow[lx][ly].bits.perm_flow_dir;

            //read the tile spatter
            readSpatterToTile(b, lx, ly, splatter); 

            //read the tile material
            readMaterialToTile(b, lx, ly, trueBlock, local, global, veins, allLayers);
        }
    }

    //add trees and other vegetation
    for(auto iter = trueBlock->plants.begin(); iter != trueBlock->plants.end(); iter++) {
        df::plant * wheat = *iter;
        assert(wheat != NULL);
        Tile* b = segment.getTile( wheat->pos.x, wheat->pos.y, wheat->pos.z);
        if(!b) {
            b = segment.ResetTile(wheat->pos.x, wheat->pos.y, wheat->pos.z, tiletype::OpenSpace);
            if(!b) {
                continue;
            }
        }
        if( b->tileShape() == tiletype_shape::TREE ||
            b->tileShape() == tiletype_shape::SAPLING ||
            b->tileShape() == tiletype_shape::SHRUB) {
                b->tree.type = wheat->flags.whole;
                b->tree.index = wheat->material;
        }
    }

    //add items
    for(auto iter = trueBlock->items.begin(); iter != trueBlock->items.end(); iter++) {
		int32_t item_index = *iter;
		df::item * found_item = df::item::find(item_index);
		if(!found_item) {
			continue;
		}
		Tile* b = segment.getTile( found_item->pos.x, found_item->pos.y, found_item->pos.z);
		if(!b) {
			b = segment.ResetTile(found_item->pos.x, found_item->pos.y, found_item->pos.z, tiletype::OpenSpace);
			if(!b) {
				continue;
			}
		}
		b->Item = ConvertItem(found_item, segment);
	}


    //add effects
    for(auto iter = trueBlock->flows.begin(); iter != trueBlock->flows.end(); iter++) {
        df::flow_info * eff = *iter;
        if(eff == NULL || eff->density <= 0) {
            continue;
        }
        Tile* b = segment.getTile( eff->pos.x, eff->pos.y, eff->pos.z);
        if(segment.CoordinateInsideSegment(eff->pos.x, eff->pos.y, eff->pos.z)) {
            if(!b) {
                b = segment.ResetTile(eff->pos.x, eff->pos.y, eff->pos.z, tiletype::OpenSpace);
                if(!b) {
                    continue;
                }
            }
            if(eff->density > b->tileeffect.density 
                || b->tileeffect.type == (df::flow_type) INVALID_INDEX) {
                    b->tileeffect.type = eff->type;
                    b->tileeffect.density = eff->density;
                    b->tileeffect.matt.index = eff->mat_index;
                    b->tileeffect.matt.type = eff->mat_type;
            }
        } 
    }
}
Пример #3
0
	bool Convert(GView *Parent)
	{
		bool Status = false;
		GProgressDlg Dlg(Parent);

		if (Store1 &&
			Store2)
		{
			if (Store1->GetStatus())
			{
				Prog = Dlg.ItemAt(0);
				Dlg.SetDescription("Converting items...");
				Dlg.SetLimits(0, Store1->GetFileSize());
				Dlg.SetScale(1.0 / 1024.0);
				Dlg.SetType("K");

				StorageItem *Item1 = Store1->GetRoot();
				ReaderItem *Reader1 = new ReaderItem(Item1);
				if (Reader1)
				{
					// The storage1 code didn't set the root object's type
					// correctly, leaving it as -1. So on the way over lets
					// correct this little mistake and make it into a folder.
					Reader1->Store->SetType(0xAAFF0003); // magic # for a folder
				}

				WriterItem *Writer2 = new WriterItem(Reader1);
				StorageItem *Item2 = Store2->CreateRoot(Writer2);
				if (Writer2 && Item2)
				{
					Writer2->Store = Item2;
					Item2->Object = Writer2;
				}

				if (Reader1 && Writer2)
				{
					Status = ConvertItem(Reader1, Writer2);

					Reader1->Store->Object = 0;
					Reader1->Store = 0;
					Writer2->Store->Object = 0;
					Writer2->Store = 0;
				}
			}
			else
			{
				GStatusPane *Wnd = dynamic_cast<GStatusPane*>(Prog);
				LgiMsg(	Wnd,
						"The input folders failed to load correctly.\n"
						"Most likely because they are not v1 folders or\n"
						"are corrupt.",
						"Scribe: Folder Compact",
						MB_OK);
			}

			DeleteObj(Store1);
			DeleteObj(Store2);
		}

		return Status;
	}