123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966 |
- /*
- * 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 : OTERRAIN.CPP
- //Description : Terrain resource object
- //Ownership : Gilbert
- #include <OIMGRES.h>
- #include <COLOR.h>
- #include <OSYS.h>
- #include <OGAMESET.h>
- #include <OWORLD.h>
- #include <OTERRAIN.h>
- #include <OCONFIG.h>
- //---------- #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 ; i<TOTAL_TERRAIN_TYPE ; i++ )
- {
- if( map_tile_name_array[i] )
- // ###### begin Gilbert 9/9 ########//
- // map_tile_ptr_array[i] = image_spict.get_ptr(map_tile_name_array[i]) + sizeof(short)*2;
- map_tile_ptr_array[i] = image_tpict.get_ptr(map_tile_name_array[i]) + sizeof(short)*2;
- // ###### end Gilbert 9/9 ########//
- }
- //-------- init terrain_type_array ---------//
- for( i=1 ; i<=TOTAL_TERRAIN_TYPE ; i++ )
- {
- terrainId = scan( i, ALL_MASK, i, ALL_MASK, i, ALL_MASK, i, ALL_MASK, 1 ); // scan for terrain of all four types. 1-take the first instance of the terrain bitmap that matches the given terrain types
- if(terrainId)
- {
- terrain_type_array[i-1].first_terrain_id = terrainId;
- terrain_type_array[i-1].last_terrain_id = terrainId + terrain_res[terrainId]->alternative_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 ; i<terrain_count ; i++ )
- {
- terrainRec = (TerrainRec*) dbTerrain->read(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.
- //
- // <int> nwType, neType, swType, seType - the base terrain types to look for
- // <int> 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 : <int> >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.
- //
- // <int> primaryType - TerrainTypeCode
- // <int> secondaryType - TerrainTypeCode
- // <int> 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 : <int> >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
- //
- // <int> nwPatternId pattern_id of a terrain,
- // obtained by terrain_res[terrain_id]->pattern_id
- // <TerrainSubInfo *> resultArray an array to be filled with matches
- // <int> maxResult the no. of elements of the resultArray
- // <int> 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
|