/*
* 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 : OTERRAIN.CPP
//Description : Terrain resource object
//Ownership : Gilbert
#include
#include
#include
#include
#include
#include
#include
//---------- #define constant ------------//
//#define TERRAIN_DB "TERRAIN"
//#define TERRAIN_SUB_DB "TERSUB"
//#define TERRAIN_ANIM_DB "TERANM"
#define MAX_TERRAIN_ANIM_FRAME 16
//-------- define base terrain colors --------//
//
// Base terrain types:
//
// -Ocean
// -Dark Grass
// -Light Grass
// -Dark Dirt
// -Light Dirt
//
//--------------------------------------------//
static int terrain_type_color_array[TOTAL_TERRAIN_TYPE] = // the color of each terrain type on the small map
{
0x20,
0x0A,
0x0D,
0x2D,
};
static char* map_tile_name_array[TOTAL_TERRAIN_TYPE] = // the color of each terrain type on the small map
{
"TERA_S",
"TERA_DG",
"TERA_LG",
"TERA_D",
};
static char* map_tile_ptr_array[TOTAL_TERRAIN_TYPE];
static int terrain_type_min_height_array[TOTAL_TERRAIN_TYPE][3] = // the color of each terrain type on the small map
{
// { 0, 5, 55 }, // S-, S0, S+
// { 60, 65, 125 }, // G-, G0, G+
// { 130, 135, 195 }, // F-, F0, F+
// { 200, 205, 250 }, // D-, D0, D+
{ 0, 20, 40 }, // S-, S0, S+
{ 60, 80, 110 }, // G-, G0, G+
{ 130, 150, 180 }, // F-, F0, F+
{ 200, 215, 240 }, // D-, D0, D+
};
// ------ Begin of function TerrainInfo::get_bitmap -------//
char *TerrainInfo::get_bitmap(unsigned frameNo)
{
return frameNo && anim_frames ? anim_bitmap_ptr[frameNo%(unsigned)anim_frames] : NULL;
}
// ------ end of function TerrainRes::terrain_code -------//
// ------ Begin of function TerrainRes::terrain_code -------//
TerrainTypeCode TerrainRes::terrain_code(char tcCode)
{
switch(tcCode)
{
case 'S':
return TERRAIN_OCEAN;
case 'G':
return TERRAIN_DARK_GRASS;
case 'F':
return TERRAIN_LIGHT_GRASS;
case 'D':
return TERRAIN_DARK_DIRT;
default:
err_here();
return TERRAIN_OCEAN;
}
}
// ------ End of static function TerrainRes::terrain_code -------//
// ------ Begin of static function TerrainRes::terrain_mask -------//
SubTerrainMask TerrainRes::terrain_mask(char subtc)
{
switch(subtc)
{
case '0':
return MIDDLE_MASK;
case '+':
return TOP_MASK;
case '-':
return BOTTOM_MASK;
case 'A':
return NOT_BOTTOM_MASK;
case 'B':
return NOT_TOP_MASK;
case '*':
return ALL_MASK;
default:
err_here();
return MIDDLE_MASK;
}
}
// ------ End of function TerrainRes::terrain_mask -------//
// ------ Begin of function TerrainRes::terrain_height -------//
int TerrainRes::terrain_height(int height, int *subPtr)
{
char tc, subtc;
for( tc = TOTAL_TERRAIN_TYPE -1; tc >= 0; --tc)
{
if( height >= terrain_type_min_height_array[tc][0])
{
for( subtc = 2; subPtr && subtc >= 0; --subtc)
{
if(height >= terrain_type_min_height_array[tc][subtc])
{
*subPtr = 1 << subtc;
break;
}
}
err_when(subtc < 0);
return tc+1;
}
}
err_here();
return 0;
}
// ------ End of function TerrainRes::terrain_height -------//
// ------ Begin of function TerrainRes::min_height ------//
short TerrainRes::min_height(TerrainTypeCode tc, SubTerrainMask subtc)
{
int s, j;
for(s=0,j=1 ; s < 3 && !(subtc & j); ++s, j+=j);
return terrain_type_min_height_array[tc-1][s];
}
// ------ End of function TerrainRes::min_height ------//
// ------ Begin of function TerrainRes::max_height ------//
short TerrainRes::max_height(TerrainTypeCode tc, SubTerrainMask subtc)
{
if( subtc & TOP_MASK )
{
if( tc < TOTAL_TERRAIN_TYPE )
return terrain_type_min_height_array[tc-1+1][0]-1;
else
return 255;
}
int s, j;
for(s=2,j=2 ; s >= 0 && !(subtc & j); --s, j>>=1);
return terrain_type_min_height_array[tc-1][s]-1;
}
// ------ End of function TerrainRes::max_height ------//
//------- Begin of function TerrainRes::TerrainRes -----------//
TerrainRes::TerrainRes()
{
init_flag=0;
}
//--------- End of function TerrainRes::TerrainRes -----------//
//---------- Begin of function TerrainRes::init -----------//
//
// This function must be called after a map is generated.
//
void TerrainRes::init()
{
deinit();
//----- open firm material bitmap resource file -------//
String str;
str = DIR_RES;
// str += "I_TERAIN.RES";
str += "I_TERN";
str += config.terrain_set;
str += ".RES";
res_bitmap.init_imported(str,1); // 1-read all into buffer
//------- load database information --------//
load_info();
load_sub_info();
str = DIR_RES;
// str += "I_TERANM.RES";
str += "I_TERA";
str += config.terrain_set;
str += ".RES";
anm_bitmap.init_imported(str,1);
load_anim_info();
//-------- init map_tile_ptr_array --------//
int i, terrainId;
for( i=0 ; ialternative_count_with_extra;
terrain_type_array[i-1].min_height = terrain_type_min_height_array[i-1][0];
}
else
{
// BUGHERE: should not reach this point after all terrain type are complete
terrain_type_array[i-1].first_terrain_id = 0;
terrain_type_array[i-1].last_terrain_id = 0;
terrain_type_array[i-1].min_height = terrain_type_min_height_array[i-1][0];
}
}
init_flag=1;
}
//---------- End of function TerrainRes::init -----------//
//---------- Begin of function TerrainRes::deinit -----------//
void TerrainRes::deinit()
{
if( init_flag )
{
for( int i = terrain_count-1; i >= 0; --i)
{
if( terrain_info_array[i].anim_frames > 0 )
mem_del(terrain_info_array[i].anim_bitmap_ptr);
}
mem_del(terrain_info_array);
mem_del(ter_sub_array);
mem_del(ter_sub_index);
init_flag=0;
}
}
//---------- End of function TerrainRes::deinit -----------//
//------- Begin of function TerrainRes::load_info -------//
//
// Read in information of TERRAIN.DBF into memory array
//
void TerrainRes::load_info()
{
TerrainRec *terrainRec;
TerrainInfo *terrainInfo = NULL;
int i;
long bitmapOffset;
//---- read in terrain count and initialize terrain info array ----//
// Database *dbTerrain = game_set.open_db(TERRAIN_DB);
String terrainDbName;
terrainDbName = DIR_RES;
terrainDbName += "TERRAIN";
terrainDbName += config.terrain_set;
terrainDbName += ".RES";
Database terrainDbObj(terrainDbName, 1);
Database *dbTerrain = &terrainDbObj;
terrain_count = (short) dbTerrain->rec_count();
terrain_info_array = (TerrainInfo*) mem_add( sizeof(TerrainInfo)*terrain_count );
memset( terrain_info_array, 0, sizeof(TerrainInfo) * terrain_count );
file_name_array = (char *) mem_add(terrainRec->FILE_NAME_LEN*terrain_count);
// ------ initial nw_type_index -------//
for(i = 0; i < TOTAL_TERRAIN_TYPE; ++i)
{
nw_type_min[i] = 0;
nw_type_max[i] = 0;
}
//---------- read in TERRAIN.DBF ---------//
char firstNw=0, firstNe, firstSw, firstSe;
char firstNwSub=0, firstNeSub, firstSwSub, firstSeSub, firstSpFlag;
int firstId;
for( i=0 ; iread(i+1);
terrainInfo = terrain_info_array+i;
memcpy(&file_name_array[i*terrainRec->FILE_NAME_LEN], terrainRec->file_name,
terrainRec->FILE_NAME_LEN);
terrainInfo->nw_type = terrain_code(terrainRec->nw_type_code[0]);
terrainInfo->nw_subtype = terrain_mask(terrainRec->nw_type_code[1]);
terrainInfo->ne_type = terrain_code(terrainRec->ne_type_code[0]);
terrainInfo->ne_subtype = terrain_mask(terrainRec->ne_type_code[1]);
terrainInfo->sw_type = terrain_code(terrainRec->sw_type_code[0]);
terrainInfo->sw_subtype = terrain_mask(terrainRec->sw_type_code[1]);
terrainInfo->se_type = terrain_code(terrainRec->se_type_code[0]);
terrainInfo->se_subtype = terrain_mask(terrainRec->se_type_code[1]);
terrainInfo->average_type = terrain_code(terrainRec->represent_type);
// ######## begin Gilbert 12/2 #######//
switch(terrainRec->extra_flag)
{
case 0: // fall through
case ' ': // fall through
case 'N': // fall through
case 'n':
terrainInfo->extra_flag = 0;
break;
default:
terrainInfo->extra_flag = 1;
}
terrainInfo->special_flag = terrainRec->special_flag==' ' ? 0 : terrainRec->special_flag;
// ######## end Gilbert 12/2 #######//
terrainInfo->secondary_type = terrain_code(terrainRec->secondary_type);
terrainInfo->pattern_id = m.atoi(terrainRec->pattern_id, terrainRec->PATTERN_ID_LEN);
//------ set alternative_count ---------//
if( firstNw == terrainInfo->nw_type &&
firstNwSub == terrainInfo->nw_subtype &&
firstNe == terrainInfo->ne_type &&
firstNeSub == terrainInfo->ne_subtype &&
firstSw == terrainInfo->sw_type &&
firstSwSub == terrainInfo->sw_subtype &&
firstSe == terrainInfo->se_type &&
firstSeSub == terrainInfo->se_subtype &&
firstSpFlag == terrainInfo->special_flag )
{
terrain_info_array[firstId-1].alternative_count_with_extra++;
if( !terrainInfo->extra_flag )
terrain_info_array[firstId-1].alternative_count_without_extra++;
// ----- record firstId - terrain_id -------//
terrainInfo->alternative_count_with_extra = firstId -1 -i;
terrainInfo->alternative_count_without_extra = firstId -1 -i;
}
else
{
// build index on nw_type
if( firstNw != terrainInfo->nw_type)
{
// --------- mark end of previous nw_type group ---------//
if(firstNw > 0)
nw_type_max[firstNw-1] = i;
// --------- mark start of new nw_type group -----------//
nw_type_min[terrainInfo->nw_type-1] = i+1;
}
firstNw = terrainInfo->nw_type;
firstNe = terrainInfo->ne_type;
firstSw = terrainInfo->sw_type;
firstSe = terrainInfo->se_type;
firstNwSub = terrainInfo->nw_subtype;
firstNeSub = terrainInfo->ne_subtype;
firstSwSub = terrainInfo->sw_subtype;
firstSeSub = terrainInfo->se_subtype;
firstSpFlag = terrainInfo->special_flag;
firstId = i+1;
}
//---- get the bitmap pointer of the terrain icon in res_icon ----//
memcpy( &bitmapOffset, terrainRec->bitmap_ptr, sizeof(long) );
terrainInfo->bitmap_ptr = res_bitmap.read_imported(bitmapOffset);
terrainInfo->anim_frames = 0;
terrainInfo->anim_bitmap_ptr = NULL;
terrainInfo->flags = 0;
if( terrainInfo->average_type != TERRAIN_OCEAN &&
terrainInfo->secondary_type != TERRAIN_OCEAN)
{
terrainInfo->flags |= TERRAIN_FLAG_SNOW;
}
}
// ------- mark end of last nw_type group -------//
if(terrainInfo && terrainInfo->nw_type > 0)
nw_type_max[terrainInfo->nw_type-1] = i;
}
//--------- End of function TerrainRes::load_info ---------//
//---- Begin of function TerrainRes::scan ------//
//
// Scan for a terrain with the specific base terrain types.
//
// nwType, neType, swType, seType - the base terrain types to look for
// nwSubType, neSubType, swSubType, seSubType - subTerrainMask
// [int] firstInstance - whether return the first instance of the terrain instead of a random instance
// (default: 0)
// [int] includeExtra - whether include extra terrain type in the scanning
// (default: 0)
// [int] special - whether search special_flag
// (default: 0)
//
// return : >0 - the id. of the terrain
// ==0 - no terrain of the specific base types found
//
int TerrainRes::scan(int nwType, int nwSubType, int neType, int neSubType,
int swType, int swSubType, int seType, int seSubType,
int firstInstance, int includeExtra, int special)
{
int terrainId = nw_type_min[nwType-1];
int terrainIdMax = nw_type_max[nwType-1];
if(terrainId <= 0 || terrainIdMax <= 0)
return 0;
TerrainInfo* terrainInfo = terrain_info_array+terrainId-1;
// int firstTerrainId=0, instanceCount=0;
for( ; terrainId<=terrainIdMax; terrainId++, terrainInfo++ )
{
if( terrainInfo->nw_type == nwType &&
terrainInfo->nw_subtype & nwSubType &&
terrainInfo->ne_type == neType &&
terrainInfo->ne_subtype & neSubType &&
terrainInfo->sw_type == swType &&
terrainInfo->sw_subtype & swSubType &&
terrainInfo->se_type == seType &&
terrainInfo->se_subtype & seSubType &&
terrainInfo->special_flag == special)
{
if( firstInstance )
return terrainId;
else
{
if( includeExtra )
{
err_when(terrainInfo->alternative_count_with_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_with_extra+1);
}
else
{
err_when(terrainInfo->alternative_count_without_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_without_extra+1);
}
}
}
else
{
//------ skip tiles of the same type and special_flag
err_when(terrainInfo->alternative_count_with_extra < 0);
terrainId += terrainInfo->alternative_count_with_extra;
terrainInfo += terrainInfo->alternative_count_with_extra;
}
}
return 0;
}
//------ End of function TerrainRes::scan ------//
//---- Begin of function TerrainRes::scan ------//
//
// Scan for a terrain with the specific base terrain types.
//
// primaryType - TerrainTypeCode
// secondaryType - TerrainTypeCode
// patternId - pattern_id in TerrainInfo
// [int] firstInstance - whether return the first instance of the terrain instead of a random instance
// (default: 0)
// [int] includeExtra - whether include extra terrain type in the scanning
// (default: 0)
// [int] special - whether search special_flag
// (default: 0)
//
// return : >0 - the id. of the terrain
// ==0 - no terrain of the specific base types found
//
int TerrainRes::scan(int primaryType, int secondaryType, int patternId,
int firstInstance, int includeExtra, int special)
{
// if patternId is zero, that means it requires a pure terrain
if( patternId == 0)
secondaryType = primaryType;
// ----------- search 1, search the lower type -------//
int terrainId = nw_type_min[min(primaryType, secondaryType)-1];
int terrainIdMax = nw_type_max[min(primaryType, secondaryType)-1];
TerrainInfo* terrainInfo = terrain_info_array+terrainId-1;
// int firstTerrainId=0, instanceCount=0;
for( ; terrainId<=terrainIdMax; terrainId++, terrainInfo++ )
{
if( ( (terrainInfo->average_type == primaryType &&
terrainInfo->secondary_type == secondaryType) ||
(terrainInfo->average_type == secondaryType &&
terrainInfo->secondary_type == primaryType)) &&
terrainInfo->pattern_id == patternId &&
terrainInfo->special_flag == special)
{
if( firstInstance )
return terrainId;
else
{
if( includeExtra )
{
err_when(terrainInfo->alternative_count_with_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_with_extra+1);
}
else
{
err_when(terrainInfo->alternative_count_without_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_without_extra+1);
}
}
}
else
{
//------ skip tiles of the same type and special_flag
err_when(terrainInfo->alternative_count_with_extra < 0);
terrainId += terrainInfo->alternative_count_with_extra;
terrainInfo += terrainInfo->alternative_count_with_extra;
}
}
// ----------- search 2, search the higher type ---------//
if( primaryType != secondaryType)
{
terrainId = nw_type_min[max(primaryType, secondaryType)-1];
terrainIdMax = nw_type_max[max(primaryType, secondaryType)-1];
terrainInfo = terrain_info_array+terrainId-1;
// int firstTerrainId=0, instanceCount=0;
for( ; terrainId<=terrainIdMax; terrainId++, terrainInfo++ )
{
if( ( (terrainInfo->average_type == primaryType &&
terrainInfo->secondary_type == secondaryType) ||
(terrainInfo->average_type == secondaryType &&
terrainInfo->secondary_type == primaryType)) &&
terrainInfo->pattern_id == patternId &&
terrainInfo->special_flag == special)
{
if( firstInstance )
return terrainId;
else
{
if( includeExtra )
{
err_when(terrainInfo->alternative_count_with_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_with_extra+1);
}
else
{
err_when(terrainInfo->alternative_count_without_extra < 0);
return terrainId + m.random(terrainInfo->alternative_count_without_extra+1);
}
}
}
else
{
//------ skip tiles of the same type and special_flag
err_when(terrainInfo->alternative_count_with_extra < 0);
terrainId += terrainInfo->alternative_count_with_extra;
terrainInfo += terrainInfo->alternative_count_with_extra;
}
}
}
return 0;
}
//------ End of function TerrainRes::scan ------//
//------------ Begin of function TerrainRes::search_pattern -----------//
//
// search first (northwest pattern id) to match a set of
// substitution pattern, to be stored in resultArray
// return the no. of matches
//
// nwPatternId pattern_id of a terrain,
// obtained by terrain_res[terrain_id]->pattern_id
// resultArray an array to be filled with matches
// maxResult the no. of elements of the resultArray
// return no. of matches
//
int TerrainRes::search_pattern(int nwPatternId, TerrainSubInfo **resultArray,
int maxResult)
{
err_when(!init_flag);
if(!resultArray || !maxResult)
return 0;
int occur = 0;
for( int i = 0; i < ter_sub_index_count; ++i)
{
if( ter_sub_index[i] && nwPatternId == ter_sub_index[i]->old_pattern_id)
{
resultArray[occur++] = ter_sub_index[i];
if( occur >= maxResult)
break;
}
}
return occur;
}
//------------ End of function TerrainRes::search_pattern -----------//
//------------ Begin of function TerrainRes::load_sub_info -----------//
void TerrainRes::load_sub_info()
{
TerrainSubRec *terrainSubRec;
TerrainSubInfo *terrainSubInfo = NULL;
int i;
//---- read in terrain count and initialize terrain info array ----//
Database terSubDbObj(DIR_RES"TERSUB.RES", 1);
//Database *dbTerrain = game_set.open_db(TERRAIN_SUB_DB);
Database *dbTerrain = &terSubDbObj;
ter_sub_rec_count = (short) dbTerrain->rec_count();
ter_sub_array = (TerrainSubInfo*) mem_add( sizeof(TerrainSubInfo)*ter_sub_rec_count );
memset( ter_sub_array, 0, sizeof(TerrainSubInfo) * ter_sub_rec_count );
//---------- read in TERSUB.DBF ---------//
short maxSubNo = 0;
for( i=0 ; i < ter_sub_rec_count ; i++ )
{
terrainSubRec = (TerrainSubRec*) dbTerrain->read(i+1);
terrainSubInfo = ter_sub_array+i;
terrainSubInfo->sub_no = m.atoi(terrainSubRec->sub_no, terrainSubRec->SUB_NO_LEN);
terrainSubInfo->step_id = m.atoi(terrainSubRec->step_id, terrainSubRec->STEP_ID_LEN);
terrainSubInfo->old_pattern_id = m.atoi(terrainSubRec->old_pattern_id, terrainSubRec->PATTERN_ID_LEN);
terrainSubInfo->new_pattern_id = m.atoi(terrainSubRec->new_pattern_id, terrainSubRec->PATTERN_ID_LEN);
// sec_adj is useful when a pure type is changing to boundary type.
// eg. a GG square can be changed to SG or GS sqare
terrainSubInfo->sec_adj = m.atoi(terrainSubRec->sec_adj, terrainSubRec->SEC_ADJ_LEN);
switch(terrainSubRec->post_move[0])
{
case 'N':
switch(terrainSubRec->post_move[1])
{
case 'E':
terrainSubInfo->post_move = 2;
break;
case 'W':
terrainSubInfo->post_move = 8;
break;
default:
terrainSubInfo->post_move = 1;
}
break;
case 'S':
switch(terrainSubRec->post_move[1])
{
case 'E':
terrainSubInfo->post_move = 4;
break;
case 'W':
terrainSubInfo->post_move = 6;
break;
default:
terrainSubInfo->post_move = 5;
}
break;
case 'E':
terrainSubInfo->post_move = 3;
break;
case 'W':
terrainSubInfo->post_move = 7;
break;
case 'X':
terrainSubInfo->post_move = 0;
break;
default:
err_here();
}
terrainSubInfo->next_step = NULL;
if( terrainSubInfo->sub_no > maxSubNo )
maxSubNo = terrainSubInfo->sub_no;
}
// ------- build ter_sub_index ------//
ter_sub_index_count = maxSubNo;
ter_sub_index = (TerrainSubInfo **) mem_add(sizeof(TerrainSubInfo *) * ter_sub_index_count);
memset(ter_sub_index, 0, sizeof(TerrainSubInfo *) * ter_sub_index_count);
TerrainSubInfo *lastTerrainSubInfo;
for( i=0 ; i < ter_sub_rec_count ; i++ )
{
terrainSubInfo = ter_sub_array+i;
if( terrainSubInfo->step_id == 1)
{
err_when(ter_sub_index[terrainSubInfo->sub_no-1] != NULL);
ter_sub_index[terrainSubInfo->sub_no-1] = terrainSubInfo;
}
else
{
// link from the next_step pointer of previous step
// search the previous record first
if( lastTerrainSubInfo && lastTerrainSubInfo->sub_no == terrainSubInfo->sub_no
&& lastTerrainSubInfo->step_id == terrainSubInfo->step_id -1)
{
lastTerrainSubInfo->next_step = terrainSubInfo;
}
else
{
// search from the array
int j;
for(j = 0; j < ter_sub_rec_count; j++)
{
if(ter_sub_array[j].sub_no == terrainSubInfo->sub_no &&
ter_sub_array[j].step_id == terrainSubInfo->step_id-1)
{
ter_sub_array[j].next_step = terrainSubInfo;
break;
}
}
err_when(j >= ter_sub_rec_count); // not found
}
}
lastTerrainSubInfo = terrainSubInfo;
}
}
//------------ End of function TerrainRes::load_sub_info -----------//
//------------ Begin of function TerrainRes::load_anim_info -------//
void TerrainRes::load_anim_info()
{
TerrainAnimRec terrainAnimRec, lastAnimRec;
int i;
long bitmapOffset;
String terAnimDbName(DIR_RES);
terAnimDbName += "TERANM";
terAnimDbName += config.terrain_set;
terAnimDbName += ".RES";
Database terAnimDbObj(terAnimDbName, 1);
// Database *dbTerAnim = game_set.open_db(TERRAIN_ANIM_DB);
Database *dbTerAnim = &terAnimDbObj;
int count = dbTerAnim->rec_count();
int animFrameCount = 0;
char *animFrameBitmap[MAX_TERRAIN_ANIM_FRAME];
memset(lastAnimRec.filename, ' ', lastAnimRec.FILE_NAME_LEN);
//---------- read in TERANM.DBF -------//
// int j,k,l;
int l;
for( i = 0; i < count; i++)
{
char* bitmapPtr;
terrainAnimRec = *(TerrainAnimRec *)(dbTerAnim->read(i+1));
memcpy( &bitmapOffset, terrainAnimRec.bitmap_ptr, sizeof(long) );
bitmapPtr = anm_bitmap.read_imported(bitmapOffset);
if( memcmp(terrainAnimRec.base_file, lastAnimRec.base_file, terrainAnimRec.FILE_NAME_LEN))
{
// string not equal
if( lastAnimRec.filename[0] != ' ' && animFrameCount > 0)
{
// replace terrainInfo->anim_frames and anim_frame_ptr
// where the bitmap filename are the same
int replaceCount = 0;
for(l = 0; l < terrain_count; ++l)
{
if( memcmp(&file_name_array[terrainAnimRec.FILE_NAME_LEN *l],
lastAnimRec.base_file, terrainAnimRec.FILE_NAME_LEN) == 0)
{
TerrainInfo *terrainInfo = terrain_info_array+l;
err_when(terrainInfo->anim_frames > 0);
terrainInfo->anim_frames = animFrameCount;
terrainInfo->anim_bitmap_ptr = (char **) mem_add(
sizeof(char *)*animFrameCount);
memcpy(terrainInfo->anim_bitmap_ptr, animFrameBitmap,
sizeof(char *)*animFrameCount);
replaceCount++;
}
}
/*
for(int special = 0; special <= 1; ++special)
{
j = scan( terrain_code(lastAnimRec.average_type),
terrain_code(lastAnimRec.secondary_type),
m.atoi(lastAnimRec.pattern_id, lastAnimRec.PATTERN_ID_LEN), 1,0,special);
if( j > 0)
{
k = terrain_info_array[j-1].alternative_count_with_extra;
for(l = j; l <= j+k; ++l)
{
if( memcmp(&file_name_array[terrainAnimRec.FILE_NAME_LEN *(l-1)],
lastAnimRec.base_file, terrainAnimRec.FILE_NAME_LEN) == 0)
{
TerrainInfo *terrainInfo = terrain_info_array+j-1;
err_when(terrainInfo->anim_frames > 0);
terrainInfo->anim_frames = animFrameCount;
terrainInfo->anim_bitmap_ptr = (char **) mem_add(
sizeof(char *)*animFrameCount);
memcpy(terrainInfo->anim_bitmap_ptr, animFrameBitmap,
sizeof(char *)*animFrameCount);
replaceCount++;
}
}
}
}
*/
err_when( replaceCount == 0);
}
lastAnimRec = terrainAnimRec;
animFrameCount = 0;
memset(animFrameBitmap, 0, sizeof(animFrameBitmap));
}
animFrameCount++;
animFrameBitmap[m.atoi(terrainAnimRec.frame_no, terrainAnimRec.FRAME_NO_LEN)-1]
= bitmapPtr;
}
if( lastAnimRec.filename[0] != ' ' && animFrameCount > 0)
{
// replace terrainInfo->anim_frames and anim_frame_ptr
// where the bitmap filename are the same
int replaceCount = 0;
for(l = 0; l < terrain_count; ++l)
{
if( memcmp(&file_name_array[terrainAnimRec.FILE_NAME_LEN *(l-1)],
lastAnimRec.base_file, terrainAnimRec.FILE_NAME_LEN) == 0)
{
TerrainInfo *terrainInfo = terrain_info_array+l-1;
err_when(terrainInfo->anim_frames > 0);
terrainInfo->anim_frames = animFrameCount;
terrainInfo->anim_bitmap_ptr = (char **) mem_add(
sizeof(char *)*animFrameCount);
memcpy(terrainInfo->anim_bitmap_ptr, animFrameBitmap,
sizeof(char *)*animFrameCount);
replaceCount++;
}
}
/*
for(int special = 0; special <= 1; ++special)
{
j = scan( terrain_code(lastAnimRec.average_type),
terrain_code(lastAnimRec.secondary_type),
m.atoi(lastAnimRec.pattern_id, lastAnimRec.PATTERN_ID_LEN), 1,0,special);
if( j > 0)
{
k = terrain_info_array[j-1].alternative_count_with_extra;
for(l = j; l <= j+k; ++l)
{
if( memcmp(&file_name_array[terrainAnimRec.FILE_NAME_LEN *(l-1)],
lastAnimRec.base_file, terrainAnimRec.FILE_NAME_LEN) == 0)
{
TerrainInfo *terrainInfo = terrain_info_array+j-1;
err_when(terrainInfo->anim_frames > 0);
terrainInfo->anim_frames = animFrameCount;
terrainInfo->anim_bitmap_ptr = (char **) mem_add(
sizeof(char *)*animFrameCount);
memcpy(terrainInfo->anim_bitmap_ptr, animFrameBitmap,
sizeof(char *)*animFrameCount);
replaceCount++;
}
}
}
}
*/
err_when( replaceCount == 0);
}
mem_del(file_name_array);
file_name_array = NULL;
}
//------------ End of function TerrainRes::load_anim_info -------//
//----- Begin of function TerrainRes::get_tera_type_id ------//
int TerrainRes::get_tera_type_id(char* teraTypeCode)
{
return terrain_code(teraTypeCode[0]);
}
//----- End of function TerrainRes::get_tera_type_id ------//
//----- Begin of function TerrainRes::get_map_tile ------//
char* TerrainRes::get_map_tile(int terrainId)
{
return map_tile_ptr_array[terrain_res[terrainId]->average_type-1];
}
//----- End of function TerrainRes::get_map_tile ------//
#ifdef DEBUG
//---------- Begin of function TerrainRes::operator[] -----------//
TerrainInfo* TerrainRes::operator[](int terrainId)
{
err_if( terrainId<1 || terrainId>terrain_count )
err_now( "TerrainRes::operator[]" );
return terrain_info_array+terrainId-1;
}
//------------ End of function TerrainRes::operator[] -----------//
#endif