123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OPLANT.CPP
- //Description : Plant resource object
- //Owner : Gilbert
- #include <OSYS.h>
- #include <OVGA.h>
- #include <OGAMESET.h>
- #include <OWORLD.h>
- #include <OTERRAIN.h>
- #include <OINFO.h>
- #include <OPLANT.h>
- #include <OCONFIG.h>
- //---------- #define constant ------------//
- //#define PLANT_DB "PLANT"
- //#define PLANT_BITMAP_DB "PLANTBMP"
- //------- Begin of function PlantRes::PlantRes -----------//
- PlantRes::PlantRes()
- {
- init_flag=0;
- }
- //--------- End of function PlantRes::PlantRes -----------//
- //---------- Begin of function PlantRes::init -----------//
- //
- // This function must be called after a map is generated.
- //
- void PlantRes::init()
- {
- deinit();
- //----- open plant material bitmap resource file -------//
- String str;
- str = DIR_RES;
- // str += "I_PLANT.RES";
- str += "I_PLANT";
- str += config.terrain_set;
- str += ".RES";
- res_bitmap.init_imported(str,1); // 1-read all into buffer
- //------- load database information --------//
- load_plant_info();
- load_plant_bitmap();
- // ##### begin Gilbert 15/10 ########//
- plant_map_color = (char) V_DARK_GREEN;
- // ##### end Gilbert 15/10 ########//
- init_flag=1;
- }
- //---------- End of function PlantRes::init -----------//
- //---------- Begin of function PlantRes::deinit -----------//
- void PlantRes::deinit()
- {
- if( init_flag )
- {
- mem_del(plant_info_array);
- mem_del(plant_bitmap_array);
- mem_del(scan_id_array);
- init_flag=0;
- }
- }
- //---------- End of function PlantRes::deinit -----------//
- //------- Begin of function PlantRes::load_plant_info -------//
- //
- void PlantRes::load_plant_info()
- {
- PlantRec *plantRec;
- PlantInfo *plantInfo;
- int i;
- //---- read in plant count and initialize plant info array ----//
- String plantDbName;
- plantDbName = DIR_RES;
- plantDbName += "PLANT";
- plantDbName += config.terrain_set;
- plantDbName += ".RES";
- Database plantDbObj(plantDbName, 1);
- // Database *dbPlant = game_set.open_db(PLANT_DB);
- Database *dbPlant = &plantDbObj;
- plant_count = (short) dbPlant->rec_count();
- plant_info_array = (PlantInfo*) mem_add( sizeof(PlantInfo)*plant_count );
- memset( plant_info_array, 0, sizeof(PlantInfo) * plant_count );
- //---------- read in PLANT.DBF ---------//
- for( i=0 ; i<plant_count ; i++ )
- {
- plantRec = (PlantRec*) dbPlant->read(i+1);
- plantInfo = plant_info_array+i;
- plantInfo->climate_zone = m.atoi( plantRec->climate_zone, plantRec->ZONE_LEN );
- if( plantRec->tera_type1[0] == 'T' ) // town plant
- {
- plantInfo->tera_type[0] = 'T';
- }
- else
- {
- if(plantRec->tera_type1[0] != ' ')
- plantInfo->tera_type[0] = terrain_res.get_tera_type_id( plantRec->tera_type1 );
- else
- plantInfo->tera_type[0] = 0;
- }
- if( plantRec->tera_type2[0] == 'T' ) // town plant
- {
- plantInfo->tera_type[1] = 'T';
- }
- else
- {
- if(plantRec->tera_type2[0] != ' ')
- plantInfo->tera_type[1] = terrain_res.get_tera_type_id( plantRec->tera_type2 );
- else
- plantInfo->tera_type[1] = 0;
- }
- if( plantRec->tera_type3[0] == 'T' ) // town plant
- {
- plantInfo->tera_type[2] = 'T';
- }
- else
- {
- if(plantRec->tera_type3[0] != ' ')
- plantInfo->tera_type[2] = terrain_res.get_tera_type_id( plantRec->tera_type3 );
- else
- plantInfo->tera_type[2] = 0;
- }
- plantInfo->first_bitmap = m.atoi( plantRec->first_bitmap, plantRec->FIRST_BITMAP_LEN );
- plantInfo->bitmap_count = 1+m.atoi( plantRec->bitmap_count, plantRec->BITMAP_COUNT_LEN );
- }
- }
- //--------- End of function PlantRes::load_plant_info ---------//
- //------- Begin of function PlantRes::load_plant_bitmap -------//
- //
- void PlantRes::load_plant_bitmap()
- {
- PlantBitmapRec *plantBitmapRec;
- PlantBitmap *plantBitmap;
- int i;
- long bitmapOffset;
- String plantDbName;
- plantDbName = DIR_RES;
- plantDbName += "PLANTBM";
- plantDbName += config.terrain_set;
- plantDbName += ".RES";
- Database plantDbObj(plantDbName, 1);
- // Database *dbPlantBitmap = game_set.open_db(PLANT_BITMAP_DB);
- Database *dbPlantBitmap = &plantDbObj;
- plant_bitmap_count = (short) dbPlantBitmap->rec_count();
- plant_bitmap_array = (PlantBitmap*) mem_add( sizeof(PlantBitmap)*plant_bitmap_count );
- scan_id_array = (short*) mem_add( sizeof(short)*plant_bitmap_count );
- //-------- read in PLANTBMP.DBF -------//
- memset( plant_bitmap_array, 0, sizeof(PlantBitmap) * plant_bitmap_count );
- for( i=0 ; i<plant_bitmap_count ; i++ )
- {
- plantBitmapRec = (PlantBitmapRec*) dbPlantBitmap->read(i+1);
- plantBitmap = plant_bitmap_array+i;
- plantBitmap->size = m.atoi( plantBitmapRec->size, plantBitmapRec->SIZE_LEN );
- memcpy( &bitmapOffset, plantBitmapRec->bitmap_ptr, sizeof(long) );
- plantBitmap->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
- plantBitmap->bitmap_width = *((short*)plantBitmap->bitmap_ptr);
- plantBitmap->bitmap_height = *(((short*)plantBitmap->bitmap_ptr)+1);
- plantBitmap->offset_x = m.atoi( plantBitmapRec->offset_x, plantBitmapRec->OFFSET_LEN );
- plantBitmap->offset_y = m.atoi( plantBitmapRec->offset_y, plantBitmapRec->OFFSET_LEN );
- if( plantBitmapRec->town_age >= '1' && plantBitmapRec->town_age <= '9' )
- plantBitmap->town_age = plantBitmapRec->town_age-'0';
- }
- }
- //--------- End of function PlantRes::load_plant_bitmap ---------//
- //---------- Begin of function PlantRes::scan -----------//
- //
- // Check if any plant in resource matches the given criteria and
- // return the plant bitmap id. of the matched one.
- //
- // <int> climateZone - the climate zone where the plant is.
- // (either ZONE_TROPICAL or ZONE_TEMPERATE)
- // 0 - any climate zone
- // <int> teraType - the terrain type where the plant is.
- // 0 - any terrain type
- // <int> townAge - the age level of the town.
- // 0 - any town age
- //
- // return : <int> plantBitmapId - the id. of the plant bitmap.
- //
- int PlantRes::scan(int climateZone, int teraType, int townAge)
- {
- int i, j;
- int matchCount=0;
- PlantInfo* plantInfo = plant_info_array;
- PlantBitmap* plantBitmap = plant_bitmap_array + plantInfo->first_bitmap - 1;
- //-------- scan plant id. ----------//
- for( i=0 ; i<plant_count ; i++, plantInfo++ )
- {
- if( !climateZone || (plantInfo->climate_zone & climateZone) )
- {
- if( !teraType ||
- plantInfo->tera_type[0] == teraType ||
- plantInfo->tera_type[1] == teraType ||
- plantInfo->tera_type[2] == teraType )
- {
- //------ scan plant bitmap ----------//
- plantBitmap = plant_bitmap_array + plantInfo->first_bitmap - 1;
- for( j=0 ; j<plantInfo->bitmap_count ; j++, plantBitmap++ )
- {
- if( !townAge || plantBitmap->town_age == townAge || plantBitmap->town_age=='*' ) // * = wildcard type, could apply to any town age level
- {
- scan_id_array[matchCount++] = plantInfo->first_bitmap + j;
- err_when( matchCount > plant_bitmap_count );
- }
- }
- }
- }
- }
- //--- pick one from those plants that match the criteria ---//
- if( matchCount > 0 )
- {
- int plantBitmapId = scan_id_array[m.random(matchCount)];
- err_when( plantBitmapId < 1 || plantBitmapId > plant_bitmap_count );
- return plantBitmapId;
- }
- else
- return 0;
- }
- //---------- End of function PlantRes::scan -----------//
- //---------- Begin of function PlantRes::plant_recno ----------//
- short PlantRes::plant_recno(short bitmapId)
- {
- int i;
- PlantInfo *plantInfo = plant_info_array;
- for( i = 0; i<plant_count; ++i, plantInfo++ )
- if( plantInfo->first_bitmap <= bitmapId &&
- bitmapId < plantInfo->first_bitmap+ plantInfo->bitmap_count)
- return i+1;
- return 0;
- }
- //---------- End of function PlantRes::plant_recno ----------//
- #ifdef DEBUG
- //---------- Begin of function PlantRes::operator[] -----------//
- PlantInfo* PlantRes::operator[](int plantId)
- {
- err_if( plantId<1 || plantId>plant_count )
- err_now( "PlantRes::operator[]" );
- return plant_info_array+plantId-1;
- }
- //------------ End of function PlantRes::operator[] -----------//
- //---------- Begin of function PlantRes::get_bitmap -----------//
- PlantBitmap* PlantRes::get_bitmap(int bitmapId)
- {
- err_if( bitmapId<1 || bitmapId>plant_bitmap_count )
- err_now( "PlantRes::get_bitmap" );
- return plant_bitmap_array+bitmapId-1;
- }
- //------------ End of function PlantRes::get_bitmap -----------//
- #endif
- //------- Begin of function PlantBitmap::draw -----------//
- //
- // Draw the current plant on the map
- //
- void PlantBitmap::draw(int xLoc, int yLoc)
- {
- //---- get the inner position of the plant inside the location ----//
- Location* locPtr = world.get_loc(xLoc, yLoc);
- int innerX = locPtr->cargo_recno & 0xFF; // low byte - x inner position of the plant within the location
- int innerY = locPtr->cargo_recno >> 8; // high byte - y inner position of the plant within the location
- //----------- calculate absolute positions ------------//
- int absX1 = xLoc*ZOOM_LOC_WIDTH +innerX-ZOOM_LOC_WIDTH/2 +offset_x;
- int absY1 = yLoc*ZOOM_LOC_HEIGHT+innerY-ZOOM_LOC_HEIGHT/2+offset_y;
- int absX2 = absX1 + bitmap_width - 1;
- int absY2 = absY1 + bitmap_height - 1;
- //-------- check if the firm is within the view area --------//
- int x1 = absX1 - World::view_top_x;
- if( x1 <= -bitmap_width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
- return;
- int y1 = absY1 - World::view_top_y;
- if( y1 <= -bitmap_height || y1 >= ZOOM_HEIGHT )
- return;
- //------- decide which approach to use for displaying -----//
- int x2 = absX2 - World::view_top_x;
- int y2 = absY2 - World::view_top_y;
- //---- only portion of the sprite is inside the view area ------//
- if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
- {
- vga_back.put_bitmap_area_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr,
- max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1 );
- }
- //---- the whole sprite is inside the view area ------//
- else
- {
- vga_back.put_bitmap_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr );
- }
- }
- //--------- End of function PlantBitmap::draw -----------//
- //------- Begin of function PlantBitmap::draw_at -----------//
- //
- // Draw the plant on the zoom map, given the exact pixel position to put
- // the bitmap.
- //
- // <int> absBaseX, absBaseY - the absolute base (center-bottom) coordination
- // of the building.
- //
- // Draw the current plant on the map
- //
- void PlantBitmap::draw_at(int absBaseX, int absBaseY)
- {
- int absX1 = absBaseX - bitmap_width/2;
- int absY1 = absBaseY - bitmap_height;
- int absX2 = absX1 + bitmap_width - 1;
- int absY2 = absY1 + bitmap_height - 1;
- //-------- check if the firm is within the view area --------//
- int x1 = absX1 - World::view_top_x;
- if( x1 <= -bitmap_width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
- return;
- int y1 = absY1 - World::view_top_y;
- if( y1 <= -bitmap_height || y1 >= ZOOM_HEIGHT )
- return;
- //------- decide which approach to use for displaying -----//
- int x2 = absX2 - World::view_top_x;
- int y2 = absY2 - World::view_top_y;
- //---- only portion of the sprite is inside the view area ------//
- if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
- {
- int srcX1 = 0;
- int srcY1 = 0;
- int srcX2 = bitmap_width - 1;
- int srcY2 = bitmap_height - 1;
- if( x1 < 0 ) // get a starting location towards more right
- srcX1 -= x1;
- if( y1 < 0 )
- srcY1 -= y1; // get a starting location towards more bottom
- if( x2 >= ZOOM_WIDTH )
- srcX2 -= x2-(ZOOM_WIDTH-1);
- if( y2 >= ZOOM_HEIGHT )
- srcY2 -= y2-(ZOOM_HEIGHT-1);
- vga_back.put_bitmap_area_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1,
- bitmap_ptr, srcX1, srcY1, srcX2, srcY2 );
- }
- //---- the whole sprite is inside the view area ------//
- else
- {
- vga_back.put_bitmap_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr );
- }
- }
- //--------- End of function PlantBitmap::draw_at -----------//
|