/*
* 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 .
*
*/
//Filename : OPLANT.CPP
//Description : Plant resource object
//Owner : Gilbert
#include
#include
#include
#include
#include
#include
#include
#include
//---------- #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 ; iread(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 ; iread(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.
//
// climateZone - the climate zone where the plant is.
// (either ZONE_TROPICAL or ZONE_TEMPERATE)
// 0 - any climate zone
// teraType - the terrain type where the plant is.
// 0 - any terrain type
// townAge - the age level of the town.
// 0 - any town age
//
// return : 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 ; iclimate_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 ; jbitmap_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; ifirst_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.
//
// 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 -----------//