12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402 |
- /*
- * 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 : OWORLD.CPP
- //Description : Object World
- #include <OSYS.h>
- #include <OGAME.h>
- #include <OVGA.h>
- #include <OFONT.h>
- #include <OMOUSE.h>
- #include <OMOUSECR.h>
- #include <OFIRMRES.h>
- #include <OPLANT.h>
- #include <OPOWER.h>
- #include <OSITE.h>
- #include <OINFO.h>
- #include <OTOWN.h>
- #include <ONATION.h>
- #include <OWEATHER.h>
- #include <OTERRAIN.h>
- #include <OWORLD.h>
- #include <OANLINE.h>
- #include <OTORNADO.h>
- #include <OU_VEHI.h>
- #include <OSERES.h>
- #include <OREMOTE.h>
- #include <ONEWS.h>
- //------------ Define static class variables ------------//
- short World::view_top_x, World::view_top_y;
- int World::max_x_loc=200, World::max_y_loc=200;
- //----------- Begin of function World::World ----------//
- World::World()
- {
- memset( this, 0, sizeof(World) );
- //------- initialize matrix objects -------//
- map_matrix = new MapMatrix;
- zoom_matrix = new ZoomMatrix;
- }
- //------------- End of function World::World -----------//
- //----------- Begin of function World::~World ----------//
- World::~World()
- {
- if( map_matrix )
- {
- delete map_matrix;
- map_matrix = NULL;
- }
- if( zoom_matrix )
- {
- delete zoom_matrix;
- zoom_matrix = NULL;
- }
- deinit();
- }
- //------------- End of function World::~World -----------//
- //----------- Begin of function World::init ----------//
- void World::init()
- {
- //----------- initialize vars -------------//
- scan_fire_x = 0;
- scan_fire_y = 0;
- lightning_signal = 0;
- map_matrix->init_para();
- zoom_matrix->init_para();
- }
- //------------- End of function World::init -----------//
- //----------- Begin of function World::deinit ----------//
- void World::deinit()
- {
- if( loc_matrix )
- {
- mem_del( loc_matrix );
- loc_matrix = NULL;
- }
- }
- //------------- End of function World::deinit -----------//
- //--------- Begin of function World::assign_map ----------//
- //
- // After a map is loaded, assign_map() need to be called to
- // initial map_matrix and zoom_matrix
- //
- void World::assign_map()
- {
- //------------- assign map -------------//
- map_matrix-> assign_map(loc_matrix, max_x_loc, max_y_loc );
- zoom_matrix->assign_map(loc_matrix, max_x_loc, max_y_loc );
- //-------- set the zoom area box on map matrix ------//
- map_matrix->cur_x_loc = 0;
- map_matrix->cur_y_loc = 0;
- map_matrix->cur_cargo_width = zoom_matrix->disp_x_loc;
- map_matrix->cur_cargo_height = zoom_matrix->disp_y_loc;
- }
- //----------- End of function World::assign_map ----------//
- //----------- Begin of function World::paint ------------//
- //
- // Paint world window and scroll bars
- //
- void World::paint()
- {
- map_matrix->paint();
- zoom_matrix->paint();
- }
- //----------- End of function World::paint ------------//
- //----------- Begin of function World::refresh ------------//
- //
- void World::refresh()
- {
- map_matrix->refresh();
- zoom_matrix->refresh();
- }
- //----------- End of function World::refresh ------------//
- //----------- Begin of function World::process ------------//
- //
- // Called every frame
- //
- void World::process()
- {
- //-------- process wall ----------//
- form_world_wall();
- //-------- process fire -----------//
- // BUGHERE : set Location::flammability for every change in cargo
- world.spread_fire(weather);
- // ------- process visibility --------//
- process_visibility();
- //-------- process lightning ------//
- // ###### begin Gilbert 11/8 ########//
- if(lightning_signal== 0 && weather.is_lightning())
- {
- // ------- create new lightning ----------//
- lightning_signal = 110;
- }
- if( lightning_signal == 106 && config.weather_effect)
- {
- lightning_strike(m.random(MAX_MAP_WIDTH), m.random(MAX_MAP_HEIGHT), 1);
- }
- if(lightning_signal == 100)
- lightning_signal = 5 + m.random(10);
- else if( lightning_signal)
- lightning_signal--;
- // ###### end Gilbert 11/8 ########//
- //---------- process ambient sound ---------//
- if( sys.frame_count%10 == 0 ) // process once per ten frames
- process_ambient_sound();
- // --------- update scan fire x y ----------//
- if(++scan_fire_x >= SCAN_FIRE_DIST)
- {
- scan_fire_x = 0;
- if( ++scan_fire_y >= SCAN_FIRE_DIST)
- scan_fire_y =0;
- }
- }
- //----------- End of function World::process ------------//
- //----------- Begin of function World::next_day ------------//
- //
- // Called every frame
- //
- void World::next_day()
- {
- plant_ops();
- weather = weather_forecast[0];
- for(int foreDay=0; foreDay < MAX_WEATHER_FORECAST-1; ++foreDay)
- {
- weather_forecast[foreDay] = weather_forecast[foreDay+1];
- }
- weather_forecast[MAX_WEATHER_FORECAST-1].next_day();
- // ####### begin Gilbert 11/7 #########//
- magic_weather.next_day();
- // ####### end Gilbert 11/7 #########//
- if(weather.has_tornado() && config.weather_effect)
- {
- tornado_array.add_tornado(weather.tornado_x_loc(max_x_loc, max_y_loc),
- weather.tornado_y_loc(max_x_loc, max_y_loc), 600);
- }
- // ######## begin Gilbert 31/7 #######//
- if( weather.is_quake() && config.random_event_frequency)
- // ######## end Gilbert 31/7 #######//
- {
- earth_quake();
- }
- //-------- Debug code: BUGHERE ----------//
- #ifdef DEBUG
- Location* locPtr = loc_matrix;
- for( int y=0 ; y<MAX_WORLD_Y_LOC ; y++ )
- {
- for( int x=0 ; x<MAX_WORLD_X_LOC ; x++ )
- {
- if( locPtr->has_unit(UNIT_LAND) )
- {
- err_when( unit_array.is_truly_deleted( locPtr->unit_recno(UNIT_LAND) ) );
- }
- locPtr++;
- }
- }
- #endif
- }
- //----------- End of function World::next_day ------------//
- //----------- Begin of function World::detect ------------//
- //
- // Detect mouse action from user
- //
- // Return : 1 - mouse pressed on World area
- // 0 - mouse not pressed on World area
- //
- int World::detect()
- {
- if( map_matrix->detect() )
- return 1;
- if( zoom_matrix->detect() )
- return 1;
- if( detect_scroll() )
- return 1;
- // ##### begin Gilbert 16/9 #######//
- // return detect_firm_town();
- return 0;
- // ##### end Gilbert 16/9 #######//
- }
- //----------- End of function World::detect ------------//
- //--------- Begin of function World::detect_scroll ---------//
- //
- // Detect if the mouse cursor is pushed towards the border
- // of the screen to scroll the zoom window.
- //
- int World::detect_scroll()
- {
- if( mouse_cursor.frame_flag ) // if it's now in frame selection mode
- return 0;
- if( next_scroll_time && m.get_time() < next_scroll_time ) // just scrolled not too long ago, wait for a little while before next scroll.
- return 0;
- int rc=0;
- //----- scroll left -----//
- if( mouse.cur_x == mouse.bound_x1 )
- {
- zoom_matrix->scroll(-1,0);
- rc = 1;
- }
- //---- scroll right -----//
- if( mouse.cur_x == mouse.bound_x2 )
- {
- zoom_matrix->scroll(1,0);
- rc = 1;
- }
- //---- scroll top -------//
- if( mouse.cur_y == mouse.bound_y1 )
- {
- zoom_matrix->scroll(0,-1);
- rc = 1;
- }
- //---- scroll bottom ----//
- if( mouse.cur_y == mouse.bound_y2 )
- {
- zoom_matrix->scroll(0,1);
- rc = 1;
- }
- //----- set next scroll time based on scroll_speed -----//
- //
- // slowest scroll speed: 500/1 = 500 milliseconds or 1/2 second
- // fastest scroll speed: 500/10 = 50 milliseconds or 1/20 second
- //
- //------------------------------------------------------//
- if( rc )
- {
- sys.zoom_need_redraw = 1; // ask the zoom window to refresh next time
- next_scroll_time = m.get_time() + 500/(config.scroll_speed+1);
- }
- return rc;
- }
- //----------- End of function World::detect_scroll -----------//
- //--------- Begin of function World::go_loc --------//
- //
- // Go to a specified location.
- //
- // <int> xLoc, yLoc - location to go to.
- // [int] selectFlag - whether should the object on the location if
- // there is one. (default: 0)
- //
- void World::go_loc(int xLoc, int yLoc, int selectFlag)
- {
- //------- set location ---------//
- zoom_matrix->cur_x_loc = xLoc;
- zoom_matrix->cur_y_loc = yLoc;
- map_matrix->cur_x_loc = xLoc - zoom_matrix->disp_x_loc/2;
- map_matrix->cur_y_loc = yLoc - zoom_matrix->disp_y_loc/2;
- //--------- refresh ------------//
- map_matrix->valid_cur_box();
- zoom_matrix->top_x_loc = map_matrix->cur_x_loc;
- zoom_matrix->top_y_loc = map_matrix->cur_y_loc;
- sys.zoom_need_redraw = 1;
- //---- if should select the object on the location ----//
- if( selectFlag )
- {
- Location* locPtr = world.get_loc(xLoc, yLoc);
- if( locPtr->has_any_unit() )
- {
- int mobileType;
- int unitRecno = locPtr->get_any_unit( mobileType );
- power.reset_selection();
- unit_array[unitRecno]->selected_flag = 1;
- unit_array.selected_recno = unitRecno;
- unit_array.selected_count++;
- }
- else if( locPtr->is_firm() )
- {
- power.reset_selection();
- firm_array.selected_recno = locPtr->firm_recno();
- }
- else if( locPtr->is_town() )
- {
- power.reset_selection();
- town_array.selected_recno = locPtr->town_recno();
- }
- else if( locPtr->has_site() )
- {
- power.reset_selection();
- site_array.selected_recno = locPtr->site_recno();
- }
- }
- //------- refresh the display -------//
- info.disp();
- }
- //----------- End of function World::go_loc --------//
- //-------- Begin of function World::unveil ---------//
- //
- // Unveil all surrounding areas of the given object.
- //
- // <int> xLoc1, yLoc1 = the position of the object.
- // <int> xLoc2, yLoc2 = the position of the object.
- //
- void World::unveil(int xLoc1, int yLoc1, int xLoc2, int yLoc2)
- {
- if( config.explore_whole_map )
- return;
- xLoc1 = max( 0, xLoc1 - EXPLORE_RANGE);
- yLoc1 = max( 0, yLoc1 - EXPLORE_RANGE);
- xLoc2 = min( MAX_WORLD_X_LOC-1, xLoc2 + EXPLORE_RANGE);
- yLoc2 = min( MAX_WORLD_Y_LOC-1, yLoc2 + EXPLORE_RANGE);
- explore( xLoc1, yLoc1, xLoc2, yLoc2 );
- }
- //--------- End of function World::unveil ---------//
- //-------- Begin of function World::explore ---------//
- //
- // Explore a specific area. No further exploration around the area.
- //
- // <int> xLoc1, yLoc1 = the position of the area.
- // <int> xLoc2, yLoc2 = the position of the area.
- //
- void World::explore(int xLoc1, int yLoc1, int xLoc2, int yLoc2)
- {
- if( config.explore_whole_map )
- return;
- int xLoc, yLoc;
- Location* locPtr;
- char* imageBuf = map_matrix->save_image_buf + sizeof(short)*2;
- char* nationColorArray = nation_array.nation_power_color_array;
- char* writePtr;
- int shadowMapDist = max_x_loc + 1;
- int tileYOffset;
- Location *northWestPtr;
- char tilePixel;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- if( !locPtr->explored() )
- {
- locPtr->explored_on();
- //-------- draw pixel ----------//
- writePtr = imageBuf+MAP_WIDTH*yLoc+xLoc;
- switch( world.map_matrix->map_mode )
- {
- case MAP_MODE_TERRAIN:
- if( locPtr->fire_str() > 0)
- *writePtr = (char) FIRE_COLOR;
- else if( locPtr->is_plant() )
- *writePtr = plant_res.plant_map_color;
- else
- {
- tileYOffset = (yLoc & TERRAIN_TILE_Y_MASK) * TERRAIN_TILE_WIDTH;
- tilePixel = terrain_res.get_map_tile(locPtr->terrain_id)[tileYOffset + (xLoc & TERRAIN_TILE_X_MASK)];
- if( xLoc == 0 || yLoc == 0)
- {
- *writePtr = tilePixel;
- }
- else
- {
- northWestPtr = locPtr - shadowMapDist;
- if( (terrain_res[locPtr->terrain_id]->average_type >=
- terrain_res[northWestPtr->terrain_id]->average_type) )
- {
- *writePtr = tilePixel;
- }
- else
- {
- *writePtr = (char) VGA_GRAY;
- }
- }
- break;
- }
- break;
- case MAP_MODE_SPOT:
- if( locPtr->sailable() )
- *writePtr = (char) 0x32;
- else if( locPtr->has_hill() )
- *writePtr = (char) V_BROWN;
- else if( locPtr->is_plant() )
- *writePtr = (char) V_DARK_GREEN;
- else
- *writePtr = (char) VGA_GRAY+10;
- break;
- case MAP_MODE_POWER:
- if( locPtr->sailable() )
- *writePtr = (char) 0x32;
- else if( locPtr->has_hill() )
- *writePtr = (char) V_BROWN;
- else if( locPtr->is_plant() )
- *writePtr = (char) V_DARK_GREEN;
- else
- *writePtr = nationColorArray[locPtr->power_nation_recno];
- break;
- }
- //---- if the command base of the opponent revealed, establish contact ----//
- if( locPtr->is_firm() )
- {
- Firm* firmPtr = firm_array[locPtr->firm_recno()];
- if( firmPtr->nation_recno > 0 && nation_array.player_recno )
- {
- NationRelation *relation = (~nation_array)->get_relation(firmPtr->nation_recno);
- if( !relation->has_contact )
- {
- if( !remote.is_enable() )
- {
- (~nation_array)->establish_contact(firmPtr->nation_recno);
- }
- else
- {
- if( !relation->contact_msg_flag )
- {
- // packet structure : <player nation> <explored nation>
- short *shortPtr = (short *)remote.new_send_queue_msg(MSG_NATION_CONTACT, 2*sizeof(short));
- *shortPtr = nation_array.player_recno;
- shortPtr[1] = firmPtr->nation_recno;
- relation->contact_msg_flag = 1;
- }
- }
- }
- }
- }
- if( locPtr->is_town() )
- {
- Town* townPtr = town_array[locPtr->town_recno()];
- if( townPtr->nation_recno > 0 && nation_array.player_recno )
- {
- NationRelation *relation = (~nation_array)->get_relation(townPtr->nation_recno);
- if( !relation->has_contact )
- {
- if( !remote.is_enable() )
- {
- (~nation_array)->establish_contact(townPtr->nation_recno);
- }
- else
- {
- if( !relation->contact_msg_flag )
- {
- // packet structure : <player nation> <explored nation>
- short *shortPtr = (short *)remote.new_send_queue_msg(MSG_NATION_CONTACT, 2*sizeof(short));
- *shortPtr = nation_array.player_recno;
- shortPtr[1] = townPtr->nation_recno;
- relation->contact_msg_flag = 1;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- //--------- End of function World::explore ---------//
- //-------- Begin of function World::is_explored ---------//
- //
- // Check if the whole area has been explored or not.
- //
- // <int> xLoc1, yLoc1 = the coordination of the area to explore
- // <int> xLoc2, yLoc2 = the coordination of the area to explore
- //
- int World::is_explored(int xLoc1, int yLoc1, int xLoc2, int yLoc2)
- {
- if( config.explore_whole_map )
- return 1;
- int xLoc, yLoc;
- Location* locPtr;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- if( !locPtr->explored() )
- return 0;
- }
- }
- return 1;
- }
- //--------- End of function World::is_explored ---------//
- //----------- Begin of function World::load_map ------------//
- //
- // Load a custom map file.
- //
- void World::load_map(char* fileName)
- {
- generate_map();
- return;
- //---------- initialize the map matrix --------//
- max_x_loc = 200;
- max_y_loc = 200;
- loc_matrix = (Location*) mem_resize( loc_matrix , max_x_loc * max_y_loc * sizeof(Location) );
- memset( loc_matrix, 0, sizeof(Location) * max_x_loc * max_y_loc );
- int baseType = TERRAIN_DARK_DIRT;
- int terrainId = terrain_res.scan(baseType, MIDDLE_MASK, baseType, MIDDLE_MASK,
- baseType, MIDDLE_MASK, baseType, MIDDLE_MASK, 1); // 1-get the first instance
- for( int i=0 ; i<max_x_loc*max_y_loc ; i++ )
- {
- loc_matrix[i].terrain_id = terrainId+m.random(3);
- }
- assign_map();
- return;
- //---------- initialize the map matrix --------//
- max_x_loc = 120;
- max_y_loc = 120;
- loc_matrix = (Location*) mem_resize( loc_matrix , max_x_loc * max_y_loc * sizeof(Location) );
- //-------------- read in the map -------------//
- File mapFile;
- mapFile.file_open(fileName);
- mapFile.file_read(loc_matrix, sizeof(Location)*MAX_WORLD_X_LOC*MAX_WORLD_Y_LOC );
- mapFile.file_close();
- //----- assign the map to MapMatrix and ZoomMatrix -----//
- assign_map();
- }
- //----------- End of function World::load_map ------------//
- //-------- Begin of function World::check_unit_space ------//
- //
- // To check whether or not the area bounded by the upper left
- // corner (xLoc1, yLoc1) and lower right corner (xLoc2, yLoc2)
- // can be built.
- //
- // <int> xLoc1 = the upper left x
- // <int> yLoc1 = the upper left y
- // <int> xLoc2 = the lower right x
- // <int> yLoc2 = the lower right y
- // [int] mobileType = mobile type (default: UNIT_LAND)
- // [int] buildFlag = whether the located area is for building a firm/town
- // if so, the location must no have any raw site.
- // (default: 0)
- //
- // return 1 for true. 0 for false
- //
- inline int World::check_unit_space(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int mobileType, int buildFlag)
- {
- if(xLoc1<0 || xLoc1>=MAX_WORLD_X_LOC)
- return 0;
- if(yLoc1<0 || yLoc1>=MAX_WORLD_Y_LOC)
- return 0;
- if(xLoc2<0 || xLoc2>=MAX_WORLD_X_LOC)
- return 0;
- if(yLoc2<0 || yLoc2>=MAX_WORLD_Y_LOC)
- return 0;
- Location* locPtr = world.get_loc(xLoc1, yLoc1);
- int x, y;
- int canBuildFlag = 1;
- for(y=yLoc1; y<=yLoc2; y++)
- {
- locPtr = world.get_loc(xLoc1, y);
- for(x=xLoc1; x<=xLoc2; x++, locPtr++)
- {
- if( !locPtr->can_move(mobileType) ||
- ( buildFlag && (locPtr->is_power_off() || locPtr->has_site()) ) ) // if build a firm/town, there must not be any sites in the area
- {
- canBuildFlag=0;
- break;
- }
- }
- if(canBuildFlag==0)
- break;
- }
- if( canBuildFlag )
- return 1;
- else
- return 0;
- }
- //-------- End of function World::check_unit_space ------//
- //-------- Begin of function World::locate_space ------//
- //
- // Locate an area in the world map around the firm to place
- // the unit
- //
- // <int&> xLoc1 = the upper left x location of the building, also for returning the result location
- // <int&> yLoc1 = the upper left y location of the building
- // <int> xLoc2 = the lower right x location of the building
- // <int> yLoc2 = the lower right y location of the building
- // <int> spaceLocWidth = the location width of the required space
- // <int> spaceLocHeight = the location height of the required space
- // [int] mobileType = mobile type (default: UNIT_LAND)
- // [int] regionId = specify the region no. of the location to locate
- // (default: region no. of xLoc1, yLoc1)
- // [int] buildFlag = whether the located area is for building a firm/town
- // if so, the location must no have any raw site.
- // (default: 0)
- //
- // return : <int> 1 - free space found
- // 0 - free space not found
- //
- int World::locate_space(int& xLoc1, int& yLoc1, int xLoc2, int yLoc2,
- int spaceLocWidth, int spaceLocHeight, int mobileType, int regionId, int buildFlag)
- {
- if( !regionId )
- regionId = get_loc(xLoc1, yLoc1)->region_id;
- int isPlateau = get_loc(xLoc1, yLoc1)->is_plateau();
- //-----------------------------------------------------------//
- // xLoc, yLoc is the adjusted upper left corner location of
- // the firm. with the adjustment, it is easier to do the following
- // checking.
- //-----------------------------------------------------------//
- Location* locPtr;
- int xLoc = xLoc1 - spaceLocWidth + 1;
- int yLoc = yLoc1 - spaceLocHeight + 1;
- if(xLoc < 0)
- xLoc = 0;
- if(yLoc < 0)
- yLoc = 0;
- int width = xLoc2 - xLoc + 1;
- int height = yLoc2 - yLoc + 1;
- int loopCount=0;
- while(1)
- {
- err_when( ++loopCount > MAX_WORLD_X_LOC * MAX_WORLD_Y_LOC * 4 );
- //-----------------------------------------------------------//
- // step 1
- //-----------------------------------------------------------//
- int xOffset = width/2;
- int yOffset = height;
- int x, y;
- x = xLoc + xOffset;
- y = yLoc + yOffset;
- if(x>=0 && y>=0 && x+spaceLocWidth-1<MAX_WORLD_X_LOC && y+spaceLocHeight-1<MAX_WORLD_Y_LOC)
- {
- if(mobileType==UNIT_LAND || (x%2==0 && y%2==0))
- {
- locPtr = get_loc(x,y);
- if( locPtr->region_id == regionId &&
- locPtr->is_plateau() == isPlateau &&
- check_unit_space(x, y, x+spaceLocWidth-1, y+spaceLocHeight-1, mobileType, buildFlag))
- {
- xLoc1 = x;
- yLoc1 = y;
- return 1;
- }
- }
- }
- int sign = -1;
- int i, j, k, limit;
- //-----------------------------------------------------------//
- // step 2
- //-----------------------------------------------------------//
- //y = yLoc + yOffset;
- limit = width + 2;
- for(i=1; i<limit; i++)
- {
- xOffset += sign * i;
- x = xLoc + xOffset;
- if(x>=0 && y>=0 && x+spaceLocWidth-1<MAX_WORLD_X_LOC && y+spaceLocHeight-1<MAX_WORLD_Y_LOC)
- {
- if(mobileType==UNIT_LAND || (x%2==0 && y%2==0))
- {
- locPtr = get_loc(x,y);
- if( locPtr->region_id == regionId &&
- locPtr->is_plateau() == isPlateau &&
- check_unit_space(x, y, x+spaceLocWidth-1, y+spaceLocHeight-1, mobileType, buildFlag))
- {
- xLoc1 = x;
- yLoc1 = y;
- return 1;
- }
- }
- }
- sign *= -1;
- }
- //-----------------------------------------------------------//
- // step 3
- //-----------------------------------------------------------//
- i = limit-1;
- limit = (height+1)*2;
- int r = sign*i;
- int lastX = xOffset;
- //int lastY = yOffset;
- for(j=0; j<limit; j++)
- {
- if(j%2)
- {
- //x = xLoc + lastX;
- xOffset = lastX;
- x = xLoc + xOffset;
- //y = yLoc + yOffset;
- if(x>=0 && y>=0 && x+spaceLocWidth-1<MAX_WORLD_X_LOC && y+spaceLocHeight-1<MAX_WORLD_Y_LOC)
- {
- if(mobileType==UNIT_LAND || (x%2==0 && y%2==0))
- {
- locPtr = get_loc(x,y);
- if( locPtr->region_id == regionId &&
- locPtr->is_plateau() == isPlateau &&
- check_unit_space(x, y, x+spaceLocWidth-1, y+spaceLocHeight-1, mobileType, buildFlag))
- {
- xLoc1 = x;
- yLoc1 = y;
- return 1;
- }
- }
- }
- }
- else
- {
- xOffset = lastX + r;
- yOffset--;
- x = xLoc + xOffset;
- y = yLoc + yOffset;
- if(x>=0 && y>=0 && x+spaceLocWidth-1<MAX_WORLD_X_LOC && y+spaceLocHeight-1<MAX_WORLD_Y_LOC)
- {
- if(mobileType==UNIT_LAND || (x%2==0 && y%2==0))
- {
- locPtr = get_loc(x,y);
- if( locPtr->region_id == regionId &&
- locPtr->is_plateau() == isPlateau &&
- check_unit_space(x, y, x+spaceLocWidth-1, y+spaceLocHeight-1, mobileType, buildFlag))
- {
- xLoc1 = x;
- yLoc1 = y;
- return 1;
- }
- }
- }
- }
- }
- //-----------------------------------------------------------//
- // step 4
- //-----------------------------------------------------------//
- y = yLoc + yOffset;
- for(k=0; k<=width; k++)
- {
- sign *= -1;
- i--;
- r = sign*i;
- xOffset -= r;
- x = xLoc + xOffset;
- if(x>=0 && y>=0 && x+spaceLocWidth-1<MAX_WORLD_X_LOC && y+spaceLocHeight-1<MAX_WORLD_Y_LOC)
- {
- if(mobileType==UNIT_LAND || (x%2==0 && y%2==0))
- {
- locPtr = get_loc(x,y);
- if( locPtr->region_id == regionId &&
- locPtr->is_plateau() == isPlateau &&
- check_unit_space(x, y, x+spaceLocWidth-1, y+spaceLocHeight-1, mobileType, buildFlag))
- {
- xLoc1 = x;
- yLoc1 = y;
- return 1;
- }
- }
- }
- }
- //-----------------------------------------------------------//
- // re-init the parameters
- //-----------------------------------------------------------//
- if(xLoc<=0 && yLoc<=0 && width>=MAX_WORLD_X_LOC && height>=MAX_WORLD_Y_LOC)
- break; // the whole map has been checked
- width += 2;
- height += 2;
- xLoc -= 1;
- yLoc -= 1;
- if(xLoc<0)
- {
- xLoc = 0;
- width--;
- }
- if(yLoc<0)
- {
- yLoc=0;
- height--;
- }
- if(xLoc+width>MAX_WORLD_X_LOC)
- width--;
- if(yLoc+height>MAX_WORLD_Y_LOC)
- height--;
- //if(width==xLoc2-xLoc1+spaceLocWidth && height==yLoc2-yLoc1+spaceLocHeight) // terminate the checking
- // return 0;
- }
- return 0;
- }
- //-------- End of function World::locate_space ------//
- //-------- Begin of function World::locate_space_random ------//
- //
- // Locate an area of space in the world map randomly. Pick any
- // space available in that area without a specific scanning order.
- //
- // <int&> xLoc1 = the scaning range, also for returning the result location
- // <int&> yLoc1 = the scaning range
- // <int> xLoc2 = the scaning range
- // <int> yLoc2 = the scaning range
- // <int> spaceLocWidth = the location width of the required space
- // <int> spaceLocHeight = the location height of the required space
- // <int> maxTries = maximum no. of tries
- // [int] regionId = if this is specified, the result location will
- // be in this region.
- // [int] buildSite = whether locating space for building a site
- // (default: 0)
- // [char] teraMask = terrain mask (default: 1)
- //
- // return : <int> 1 - free space found
- // 0 - free space found
- //
- int World::locate_space_random(int& xLoc1, int& yLoc1, int xLoc2, int yLoc2,
- int spaceLocWidth, int spaceLocHeight, int maxTries,
- int regionId, int buildSite, char teraMask)
- {
- int i, x, y, xTemp, xLoc, yLoc, canBuildFlag;
- int scanWidth = xLoc2-xLoc1-spaceLocWidth+2; //xLoc2-xLoc1+1-spaceLocWidth+1;
- int scanHeight = yLoc2-yLoc1-spaceLocHeight+2; //yLoc2-yLoc1+1-spaceLocHeight+1;
- Location* locPtr;
- for( i=0 ; i<maxTries ; i++ )
- {
- xLoc = xLoc1 + m.random(scanWidth);
- yLoc = yLoc1 + m.random(scanHeight);
- canBuildFlag=1;
- //---------- check if the area is all free ----------//
- xTemp = xLoc+spaceLocWidth-1;
- for( y=yLoc+spaceLocHeight-1; y>=yLoc; y-- )
- {
- locPtr = world.get_loc(xTemp, y);
- for(x=xTemp; x>=xLoc; x--, locPtr-- )
- {
- if( ( buildSite ? !locPtr->can_build_site(teraMask) : !locPtr->can_build_firm(teraMask) ) ||
- locPtr->is_power_off() )
- {
- canBuildFlag=0;
- break;
- }
- }
- if(!canBuildFlag)
- break;
- }
- if( !canBuildFlag )
- continue;
- //------ check region id. ------------//
- locPtr = world.get_loc(xLoc, yLoc);
- if( regionId && locPtr->region_id != regionId )
- continue;
- //------------------------------------//
- xLoc1 = xLoc;
- yLoc1 = yLoc;
- err_when(buildSite && !locPtr->can_build_site(teraMask));//-*** hard codes for mine size 3x3
- return 1;
- }
- return 0;
- }
- //-------- End of function World::locate_space_random ------//
- //-------- Begin of function World::can_build_firm ---------//
- //
- // Check if it is free to construct a building on the specific area.
- //
- // <int> xLoc1, yLoc1 = the coordination of the area to can_build
- // <int> firmId = id. of the firm
- // [short] unitRecno = the unit recno of the unit to build the firm
- // if the builder unit stands on the building area, still consider the area as buildable
- // (default: -1, do not take the builder into account)
- //
- int World::can_build_firm(int xLoc1, int yLoc1, int firmId, short unitRecno)
- {
- if( xLoc1 < 0 || yLoc1 < 0 || xLoc1 > MAX_WORLD_X_LOC || yLoc1 > MAX_WORLD_Y_LOC )
- return 0;
- //------------------------------------------//
- FirmInfo* firmInfo = firm_res[firmId];
- int xLoc, yLoc;
- int xLoc2 = xLoc1 + firmInfo->loc_width - 1;
- int yLoc2 = yLoc1 + firmInfo->loc_height - 1;
- if(xLoc2>=max_x_loc || yLoc2>max_y_loc)
- return 0;
- Location* locPtr;
- char teraMask, pierFlag;
- switch(firmInfo->tera_type)
- {
- case 1: // default : land firm
- case 2: // sea firm
- case 3: // land or sea firm
- teraMask = firmInfo->tera_type;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- // ##### patch begin Gilbert 14/3 ######//
- if(!locPtr->can_build_firm(teraMask) &&
- (!locPtr->has_unit(UNIT_LAND) || locPtr->unit_recno(UNIT_LAND)!=unitRecno))
- return 0;
- // ##### patch end Gilbert 14/3 ######//
- if( firmId != FIRM_MINE && locPtr->has_site() ) // don't allow building any buildings other than mines on a location with a site
- return 0;
- }
- }
- return 1;
- case 4: // special firm, such as harbor
- // must be 3x3,
- // centre square of one side is land (teraMask=1),
- // two squares on that side can be land or sea (teraMask=3)
- // and other (6 squares) are sea (teraMask=2)
- if( firmInfo->loc_width != 3 ||
- firmInfo->loc_height != 3)
- return 0;
- pierFlag = 1|2|4|8; // bit0=north, bit1=south, bit2=west, bit3=east
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- if( locPtr->has_site() ) // don't allow building any buildings other than mines on a location with a site
- return 0;
- static char northPierTera[3][3] = { {2,2,2},{2,2,2},{3,1,3} };
- static char southPierTera[3][3] = { {3,1,3},{2,2,2},{2,2,2} };
- static char westPierTera[3][3] = { {2,2,3},{2,2,1},{2,2,3} };
- static char eastPierTera[3][3] = { {3,2,2},{1,2,2},{3,2,2} };
- int x = xLoc - xLoc1;
- int y = yLoc - yLoc1;
- if(!locPtr->can_build_harbor(northPierTera[y][x]) )
- pierFlag &= ~1;
- if(!locPtr->can_build_harbor(southPierTera[y][x]) )
- pierFlag &= ~2;
- if(!locPtr->can_build_harbor(westPierTera[y][x]) )
- pierFlag &= ~4;
- if(!locPtr->can_build_harbor(eastPierTera[y][x]) )
- pierFlag &= ~8;
- }
- }
- err_when( pierFlag != 0 && pierFlag != 1 && pierFlag != 2 &&
- pierFlag != 4 && pierFlag != 8 );
- return pierFlag;
- break;
- // other tera_type here
- default:
- err_here();
- return 0;
- }
- }
- //--------- End of function World::can_build_firm ---------//
- //-------- Begin of function World::can_build_town ---------//
- //
- // <int> xLoc1, yLoc1 = the coordination of the area to can_build
- // [short] unitRecno = the unit recno of the unit to build the town
- // if the builder unit stands on the building area, still consider the area as buildable
- // (default: -1, do not take the builder into account)
- //
- int World::can_build_town(int xLoc1, int yLoc1, short unitRecno)
- {
- int xLoc, yLoc;
- int xLoc2 = xLoc1 + STD_TOWN_LOC_WIDTH - 1;
- int yLoc2 = yLoc1 + STD_TOWN_LOC_HEIGHT - 1;
- if(xLoc2>=max_x_loc || yLoc2>=max_y_loc)
- return 0;
- Location* locPtr;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- locPtr = get_loc(xLoc1, yLoc);
- for( xLoc=xLoc1 ; xLoc<=xLoc2 ; xLoc++, locPtr++ )
- {
- // ##### patch begin Gilbert 14/3 ######//
- // allow the building unit to stand in the area
- if( !locPtr->can_build_town() &&
- (!locPtr->has_unit(UNIT_LAND) || locPtr->unit_recno(UNIT_LAND)!=unitRecno) )
- return 0;
- // ##### patch end Gilbert 14/3 ######//
- }
- }
- return 1;
- }
- //--------- End of function World::can_build_town ---------//
- //-------- Begin of function World::can_build_wall ---------//
- //
- // <int> xLoc, yLoc = the coordination of the area to can_build
- // <int> nationRecno = recno of the builder nation.
- //
- int World::can_build_wall(int xLoc, int yLoc, short nationRecno)
- {
- Location* locPtr = get_loc(xLoc, yLoc);
- return locPtr->can_build_wall() && locPtr->power_nation_recno == nationRecno;
- }
- //--------- End of function World::can_build_wall ---------//
- //-------- Begin of function World::can_destruct_wall ---------//
- //
- // <int> xLoc, yLoc = the coordination of the area to can_build
- // <int> nationRecno = recno of the builder nation.
- //
- int World::can_destruct_wall(int xLoc, int yLoc, short nationRecno)
- {
- Location* locPtr = get_loc(xLoc, yLoc);
- return locPtr->is_wall() && locPtr->power_nation_recno == nationRecno;
- }
- //--------- End of function World::can_destruct_wall ---------//
- //---------- Begin of function World::draw_link_line -----------//
- //
- // <int> srcFirmId - id. of the source firm.
- // 0 if the source is a town
- // <int> srcTownRecno - town recno of the source town
- // 0 if the source is a firm
- // <int> srcXLoc1, srcYLoc1 - the location of the source area
- // srcXLoc2, srcYLoc2
- //
- // [int] giveEffectiveDis - use this value as the effective distance if this is given
- // (default: 0)
- //
- void World::draw_link_line(int srcFirmId, int srcTownRecno, int srcXLoc1,
- int srcYLoc1, int srcXLoc2, int srcYLoc2, int givenEffectiveDis)
- {
- if( srcFirmId == FIRM_INN ) // FirmInn's link is only for scan for neighbor inns quickly, the link line is not displayed
- return;
- //--------------------------------------//
- int srcXLoc = (srcXLoc1 + srcXLoc2)/2;
- int srcYLoc = (srcYLoc1 + srcYLoc2)/2;
- int srcX = ( ZOOM_X1 + (srcXLoc1-zoom_matrix->top_x_loc) * ZOOM_LOC_WIDTH
- + ZOOM_X1 + (srcXLoc2-zoom_matrix->top_x_loc+1) * ZOOM_LOC_WIDTH ) / 2;
- int srcY = ( ZOOM_Y1 + (srcYLoc1-zoom_matrix->top_y_loc) * ZOOM_LOC_HEIGHT
- + ZOOM_Y1 + (srcYLoc2-zoom_matrix->top_y_loc+1) * ZOOM_LOC_HEIGHT ) / 2;
- //------- draw lines connected to town ---------//
- int i, townX, townY, effectiveDis;
- Town* townPtr;
- if( givenEffectiveDis )
- effectiveDis = givenEffectiveDis;
- else
- {
- if( srcFirmId )
- effectiveDis = EFFECTIVE_FIRM_TOWN_DISTANCE;
- else
- effectiveDis = EFFECTIVE_TOWN_TOWN_DISTANCE;
- }
- if( !srcFirmId || firm_res[srcFirmId]->is_linkable_to_town ) // don't draw link line to town if it's an inn
- {
- for( i=town_array.size() ; i>0 ; i-- )
- {
- if( town_array.is_deleted(i) )
- continue;
- townPtr = town_array[i];
- if( srcTownRecno && townPtr->town_recno != srcTownRecno )
- continue;
- //-------- check the distance --------//
- if( m.points_distance( townPtr->center_x, townPtr->center_y,
- srcXLoc, srcYLoc ) > effectiveDis )
- {
- continue;
- }
- //------ check if both are on the same terrain type ------//
- if( (world.get_loc(townPtr->center_x, townPtr->center_y)->is_plateau()==1)
- != (world.get_loc(srcXLoc, srcYLoc)->is_plateau()==1) )
- {
- continue;
- }
- //---------- draw line now -----------//
- townX = ( ZOOM_X1 + (townPtr->loc_x1-zoom_matrix->top_x_loc) * ZOOM_LOC_WIDTH
- + ZOOM_X1 + (townPtr->loc_x2-zoom_matrix->top_x_loc+1) * ZOOM_LOC_WIDTH ) / 2;
- townY = ( ZOOM_Y1 + (townPtr->loc_y1-zoom_matrix->top_y_loc) * ZOOM_LOC_HEIGHT
- + ZOOM_Y1 + (townPtr->loc_y2-zoom_matrix->top_y_loc+1) * ZOOM_LOC_HEIGHT ) / 2;
- anim_line.draw_line(&vga_back, srcX, srcY, townX, townY);
- }
- }
- //------- draw lines connected to firms ---------//
- if( givenEffectiveDis )
- effectiveDis = givenEffectiveDis;
- else
- {
- if( srcFirmId )
- effectiveDis = EFFECTIVE_FIRM_FIRM_DISTANCE;
- else
- effectiveDis = EFFECTIVE_FIRM_TOWN_DISTANCE;
- }
- int firmX, firmY, linkFlag;
- Firm* firmPtr;
- for( i=firm_array.size() ; i>0 ; i-- )
- {
- if( firm_array.is_deleted(i) )
- continue;
- firmPtr = firm_array[i];
- //------ only link if the firms have relationship -----//
- if( srcFirmId )
- linkFlag = firm_res[firmPtr->firm_id]->is_linkable_to_firm(srcFirmId);
- else
- linkFlag = firm_res[firmPtr->firm_id]->is_linkable_to_town;
- if( !linkFlag )
- continue;
- //-------- check the distance --------//
- if( m.points_distance( firmPtr->center_x, firmPtr->center_y,
- srcXLoc, srcYLoc ) > effectiveDis )
- {
- continue;
- }
- //------ check if both are on the same terrain type ------//
- if( (world.get_loc(firmPtr->center_x, firmPtr->center_y)->is_plateau()==1)
- != (world.get_loc(srcXLoc, srcYLoc)->is_plateau()==1) )
- {
- continue;
- }
- //---------- draw line now -----------//
- firmX = ( ZOOM_X1 + (firmPtr->loc_x1-zoom_matrix->top_x_loc) * ZOOM_LOC_WIDTH
- + ZOOM_X1 + (firmPtr->loc_x2-zoom_matrix->top_x_loc+1) * ZOOM_LOC_WIDTH ) / 2;
- firmY = ( ZOOM_Y1 + (firmPtr->loc_y1-zoom_matrix->top_y_loc) * ZOOM_LOC_HEIGHT
- + ZOOM_Y1 + (firmPtr->loc_y2-zoom_matrix->top_y_loc+1) * ZOOM_LOC_HEIGHT ) / 2;
- anim_line.draw_line(&vga_back, srcX, srcY, firmX, firmY);
- }
- }
- //----------- End of function World::draw_link_line ------------//
- //-------- Begin of function World::set_surr_power_off ---------//
- void World::set_surr_power_off(int xLoc, int yLoc)
- {
- if(xLoc>0) // west
- get_loc(xLoc-1, yLoc)->set_power_off();
- if(xLoc<max_x_loc-1)
- get_loc(xLoc+1, yLoc)->set_power_off();
-
- if(yLoc>0) // north
- get_loc(xLoc, yLoc-1)->set_power_off();
- if(yLoc<max_y_loc-1) // south
- get_loc(xLoc, yLoc+1)->set_power_off();
- }
- //----------- End of function World::set_surr_power_off ------------//
- //-------- Begin of function World::set_all_power ---------//
- //
- void World::set_all_power()
- {
- //--------- set town's influence -----------//
- Town* townPtr;
- int i;
- for( i=town_array.size() ; i>0 ; i-- )
- {
- if( town_array.is_deleted(i) )
- continue;
- townPtr = town_array[i];
- if( !townPtr->nation_recno )
- continue;
- //------- set the influence range of this town -----//
- set_power(townPtr->loc_x1, townPtr->loc_y1, townPtr->loc_x2, townPtr->loc_y2, (char)townPtr->nation_recno);
- }
- //--------- set firm's influence -----------//
- Firm* firmPtr;
- for( i=firm_array.size() ; i>0 ; i-- )
- {
- if( firm_array.is_deleted(i) )
- continue;
- firmPtr = firm_array[i];
- if( !firmPtr->nation_recno )
- continue;
- if( !firmPtr->should_set_power )
- continue;
- //------- set the influence range of this firm -----//
- set_power(firmPtr->loc_x1, firmPtr->loc_y1, firmPtr->loc_x2, firmPtr->loc_y2, (char)firmPtr->nation_recno);
- }
- }
- //--------- End of function World::set_all_power ---------//
- //-------- Begin of function World::set_power ---------//
- //
- // <int> xLoc1, yLoc1, - area on the map which the power should be set
- // xLoc2, yLoc2
- //
- // <int> nationRcno - nation recno
- //
- void World::set_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int nationRecno)
- {
- //------- reset power_nation_recno first ------//
- int plateauResult = (get_loc((xLoc1+xLoc2)/2, (yLoc1+yLoc2)/2)->is_plateau()==1);
- int xLoc, yLoc, centerY, t;
- Location* locPtr = loc_matrix;
- xLoc1 = max( 0, xLoc1 - EFFECTIVE_POWER_DISTANCE+1);
- yLoc1 = max( 0, yLoc1 - EFFECTIVE_POWER_DISTANCE+1);
- xLoc2 = min( MAX_WORLD_X_LOC-1, xLoc2 + EFFECTIVE_POWER_DISTANCE-1);
- yLoc2 = min( MAX_WORLD_Y_LOC-1, yLoc2 + EFFECTIVE_POWER_DISTANCE-1);
- centerY = (yLoc1+yLoc2) / 2;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- t=abs(yLoc-centerY)/2;
- for( xLoc=xLoc1+t ; xLoc<=xLoc2-t ; xLoc++, locPtr++ )
- {
- locPtr = get_loc(xLoc, yLoc);
- if(locPtr->sailable())//if(!locPtr->walkable())
- continue;
- if(locPtr->is_power_off())
- continue;
- if((locPtr->is_plateau()==1) != plateauResult)
- continue;
- if(locPtr->power_nation_recno==0)
- {
- locPtr->power_nation_recno = nationRecno;
- sys.map_need_redraw = 1; // request redrawing the map next time
- }
- }
- }
- }
- //--------- End of function World::set_power ---------//
- //-------- Begin of function World::restore_power ---------//
- //
- // <int> xLoc1, yLoc1, - area on the map which the power should be restored
- // xLoc2, yLoc2
- //
- // <int> townRecno, firmRecno - either one
- //
- void World::restore_power(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int townRecno, int firmRecno)
- {
- int nationRecno;
- if( townRecno )
- {
- nationRecno = town_array[townRecno]->nation_recno;
- town_array[townRecno]->nation_recno = 0;
- }
- if( firmRecno )
- {
- nationRecno = firm_array[firmRecno]->nation_recno;
- firm_array[firmRecno]->nation_recno = 0;
- }
- //------- reset power_nation_recno first ------//
- int xLoc, yLoc, centerY, t;
- Location* locPtr = loc_matrix;
- xLoc1 = max( 0, xLoc1 - EFFECTIVE_POWER_DISTANCE+1);
- yLoc1 = max( 0, yLoc1 - EFFECTIVE_POWER_DISTANCE+1);
- xLoc2 = min( MAX_WORLD_X_LOC-1, xLoc2 + EFFECTIVE_POWER_DISTANCE-1);
- yLoc2 = min( MAX_WORLD_Y_LOC-1, yLoc2 + EFFECTIVE_POWER_DISTANCE-1);
- centerY = (yLoc1+yLoc2) / 2;
- for( yLoc=yLoc1 ; yLoc<=yLoc2 ; yLoc++ )
- {
- t=abs(yLoc-centerY)/2;
- for( xLoc=xLoc1+t ; xLoc<=xLoc2-t ; xLoc++, locPtr++ )
- {
- locPtr = get_loc(xLoc, yLoc);
- if( locPtr->power_nation_recno==nationRecno )
- {
- locPtr->power_nation_recno = 0;
- sys.map_need_redraw = 1; // request redrawing the map next time
- }
- }
- }
- //--- if some power areas are freed up, see if neighbor towns/firms should take up these power areas ----//
- if( sys.map_need_redraw ) // when calls set_all_power(), the nation_recno of the calling firm must be reset
- set_all_power();
- //------- restore the nation recno of the calling town/firm -------//
- if( townRecno )
- town_array[townRecno]->nation_recno = nationRecno;
- if( firmRecno )
- firm_array[firmRecno]->nation_recno = nationRecno;
- }
- //--------- End of function World::restore_power ---------//
- //-------- Begin of function World::detect_firm_town ---------//
- //
- int World::detect_firm_town()
- {
- // ##### begin Gilbert 19/9 ########//
- // int rc = mouse.single_click(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 2);
- if( !mouse.any_click(ZOOM_X1, ZOOM_Y1, ZOOM_X2, ZOOM_Y2, 2) )
- return 0;
- // ##### end Gilbert 19/9 ########//
- //------ detect pressing on link enable/disable sign -----//
- Firm* firmPtr;
- if( firm_array.selected_recno )
- {
- firmPtr = firm_array[firm_array.selected_recno];
- if( firmPtr->should_show_info() && // only if should_show_info() is 1, we can detect links from this firm (it is not limited to player firms, as firms with player's workers should be allowed for resigning the player worker from the firm
- firmPtr->draw_detect_link_line(1) ) // 1-detect action
- {
- return 1;
- }
- }
- Town* townPtr;
- if( town_array.selected_recno )
- {
- townPtr = town_array[town_array.selected_recno];
- if( townPtr->nation_recno==nation_array.player_recno &&
- townPtr->draw_detect_link_line(1) ) // 1-detect action
- {
- return 1;
- }
- }
- // ####### begin Gilbert 12/9 #########// see Power::detect_select
- /*
- //--------------- detect firm ------------------//
- if( rc==1 ) // left click
- {
- int mouseAbsX = mouse.cur_x - ZOOM_X1 + World::view_top_x;
- int mouseAbsY = mouse.cur_y - ZOOM_Y1 + World::view_top_y;
- int i;
- for( i=firm_array.size() ; i>0 ; i-- )
- {
- if( firm_array.is_deleted(i) )
- continue;
- firmPtr = firm_array[i];
- if( m.is_touch( mouseAbsX, mouseAbsY, mouseAbsX, mouseAbsY,
- firmPtr->abs_x1, firmPtr->abs_y1, firmPtr->abs_x2, firmPtr->abs_y2 ) )
- {
- power.reset_selection();
- firm_array.selected_recno = i;
- info.disp();
- // -------- sound effect -----------//
- if( firmPtr->nation_recno == nation_array.player_recno && se_res.mark_select_object_time() )
- {
- se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
- 'F', firmPtr->firm_id, firmPtr->under_construction ? "SELU" : "SEL" );
- }
- return 1;
- }
- }
- //----------- detect town section --------------//
- for( i=town_array.size() ; i>0 ; i-- )
- {
- if( town_array.is_deleted(i) )
- continue;
- townPtr = town_array[i];
- if( m.is_touch( mouseAbsX, mouseAbsY, mouseAbsX, mouseAbsY,
- townPtr->abs_x1, townPtr->abs_y1, townPtr->abs_x2, townPtr->abs_y2 ) )
- {
- power.reset_selection();
- town_array.selected_recno = i;
- info.disp();
- // -------- sound effect -----------//
- if( townPtr->nation_recno == nation_array.player_recno
- && se_res.mark_select_object_time() )
- {
- se_res.sound(townPtr->center_x, townPtr->center_y, 1,
- 'T', 0, "SEL" );
- }
- return 1;
- }
- }
- }
- */
- return 0;
- }
- //-------- End of function World::detect_firm_town ---------//
- //-------- Begin of function World::earth_equake ------//
- void World::earth_quake()
- {
- Location *locPtr;
- int x,y;
- for(y = 0; y < max_y_loc; ++y)
- {
- locPtr = get_loc(0,y);
- for( x = 0; x < max_x_loc; ++x, ++locPtr)
- {
- if(locPtr->is_wall() )
- {
- locPtr->attack_wall( weather.quake_rate(x,y) /2 );
- }
- }
- }
- int firmDamage = 0;
- int firmDie = 0;
- int i;
- for( i=firm_array.size() ; i>0 ; i-- )
- {
- if( firm_array.is_deleted(i) || !firm_res[firm_array[i]->firm_id]->buildable)
- continue;
- Firm *firmPtr = firm_array[i];
- x = firmPtr->center_x;
- y = firmPtr->center_y;
- firmPtr->hit_points -= weather.quake_rate(x,y);
- if( firmPtr->own_firm() )
- firmDamage++;
- if( firmPtr->hit_points <= 0)
- {
- firmPtr->hit_points = (float) 0;
- if( firmPtr->own_firm() )
- firmDie++;
- se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
- 'F', firmPtr->firm_id, "DIE" );
- firm_array.del_firm(i);
- }
- }
- int townDamage = 0;
- for( i=town_array.size() ; i>0 ; i-- )
- {
- if( town_array.is_deleted(i) )
- continue;
- Town *townPtr = town_array[i];
- int ownTown = townPtr->nation_recno == nation_array.player_recno;
- short beforePopulation = townPtr->population;
- short causalty = weather.quake_rate(townPtr->center_x, townPtr->center_y) / 10;
- for( ; causalty > 0 && !town_array.is_deleted(i); --causalty )
- {
- townPtr->kill_town_people(0);
- }
- if( town_array.is_deleted(i) )
- causalty = beforePopulation;
- else
- causalty = beforePopulation - townPtr->population;
- if(ownTown)
- townDamage += causalty;
- }
- int unitDamage = 0;
- int unitDie = 0;
- for( i=unit_array.size(); i > 0; i-- )
- {
- if( unit_array.is_deleted(i))
- continue;
- Unit *unitPtr = unit_array[i];
- // ###### begin Gilbert 30/8 ######//
- // no damage to air unit , sea unit or overseer
- if( !unitPtr->is_visible() || unitPtr->mobile_type == UNIT_AIR
- || unitPtr->mobile_type == UNIT_SEA)
- continue;
- // ###### end Gilbert 30/8 ######//
- float damage = (float) weather.quake_rate(unitPtr->cur_x_loc(),unitPtr->cur_y_loc() ) *
- unitPtr->max_hit_points / 200;
- if( damage >= unitPtr->hit_points)
- damage = unitPtr->hit_points -1;
- if( damage < (float) 5)
- damage = (float) 5;
- unitPtr->hit_points -= damage;
- if( unitPtr->is_own() )
- unitDamage++;
- if( unitPtr->hit_points <= 0)
- {
- unitPtr->hit_points = (float) 0;
- if( unitPtr->is_own() )
- unitDie++;
- }
- else
- {
- if( unit_res[unitPtr->unit_id]->solider_id &&
- weather.quake_rate(unitPtr->cur_x_loc(),unitPtr->cur_y_loc()) >= 60)
- {
- ((UnitVehicle *)unitPtr)->dismount();
- }
- }
- }
- news_array.earthquake_damage(unitDamage-unitDie, unitDie, townDamage, firmDamage-firmDie, firmDie);
- }
- //-------- End of function World::earth_equake ------//
- //-------- Begin of function World::lightning_strike ------//
- void World::lightning_strike(short cx, short cy, short radius)
- {
- short x, y;
- for( y = cy-radius; y <= cy+radius; ++y)
- {
- if( y < 0 || y >= max_y_loc)
- continue;
- for( x = cx-radius; x <= cx+radius; ++x)
- {
- if( x < 0 || x >= max_x_loc)
- continue;
- Location *locPtr = get_loc(x,y);
- if( locPtr->is_plant() )
- {
- // ---- add a fire on it ------//
- locPtr->set_fire_str(80);
- // ##### begin Gilbert 11/8 #####//
- if( locPtr->can_set_fire() && locPtr->fire_str() < 5 )
- locPtr->set_fire_str(5);
- // ##### end Gilbert 11/8 #####//
- }
- }
- }
- // ------ check hitting units -------//
- int i;
- for( i=unit_array.size(); i > 0; i-- )
- {
- if( unit_array.is_deleted(i))
- continue;
- Unit *unitPtr = unit_array[i];
- // no damage to overseer
- if( !unitPtr->is_visible())
- continue;
- if( unitPtr->cur_x_loc() <= cx+ radius &&
- unitPtr->cur_x_loc() + unitPtr->sprite_info->loc_width > cx-radius &&
- unitPtr->cur_y_loc() <= cy+radius &&
- unitPtr->cur_y_loc() + unitPtr->sprite_info->loc_height > cy-radius )
- {
- unitPtr->hit_points -= (float) unitPtr->sprite_info->lightning_damage / ATTACK_SLOW_DOWN;
- // ---- add news -------//
- if( unitPtr->is_own() )
- news_array.lightning_damage(unitPtr->cur_x_loc(), unitPtr->cur_y_loc(),
- NEWS_LOC_UNIT, i, unitPtr->hit_points <= (float) 0);
- if( unitPtr->hit_points <= 0)
- unitPtr->hit_points = (float) 0;
- }
- }
- for( i=firm_array.size() ; i>0 ; i-- )
- {
- if( firm_array.is_deleted(i) || !firm_res[firm_array[i]->firm_id]->buildable)
- continue;
- Firm *firmPtr = firm_array[i];
- if( firmPtr->loc_x1 <= cx+radius &&
- firmPtr->loc_x2 >= cx-radius &&
- firmPtr->loc_y1 <= cy+radius &&
- firmPtr->loc_y2 >= cy-radius)
- {
- firmPtr->hit_points -= (float) 50 / ATTACK_SLOW_DOWN;
- // ---- add news -------//
- if( firmPtr->own_firm() )
- news_array.lightning_damage(firmPtr->center_x, firmPtr->center_y,
- NEWS_LOC_FIRM, i, firmPtr->hit_points <= (float) 0);
- // ---- add a fire on it ------//
- Location *locPtr = get_loc(firmPtr->center_x, firmPtr->center_y);
- if( locPtr->can_set_fire() && locPtr->fire_str() < 5 )
- locPtr->set_fire_str(5);
- if( firmPtr->hit_points <= 0)
- {
- firmPtr->hit_points = (float) 0;
- se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
- 'F', firmPtr->firm_id, "DIE" );
- firm_array.del_firm(i);
- }
- }
- }
- for( i=town_array.size() ; i>0 ; i-- )
- {
- if( town_array.is_deleted(i))
- continue;
- Town *townPtr = town_array[i];
- if( townPtr->loc_x1 <= cx+radius &&
- townPtr->loc_x2 >= cx-radius &&
- townPtr->loc_y1 <= cy+radius &&
- townPtr->loc_y2 >= cy-radius)
- {
- // ---- add news -------//
- if( townPtr->nation_recno == nation_array.player_recno )
- news_array.lightning_damage(townPtr->center_x, townPtr->center_y,
- NEWS_LOC_TOWN, i, 0);
- // ---- add a fire on it ------//
- // ####### begin Gilbert 11/8 #########//
- Location *locPtr = get_loc(townPtr->center_x, townPtr->center_y);
- if( locPtr->can_set_fire() && locPtr->fire_str() < 5)
- locPtr->set_fire_str(5);
- // ####### end Gilbert 11/8 #########//
- townPtr->kill_town_people(0);
- }
- }
- }
- //-------- End of function World::lightning_strike -------//
- // ------- Begin of function World::visit -----------//
- // set the visit_level surrounding unit, town and firm
- void World::visit(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int range, int extend)
- {
- if(config.fog_of_war)
- {
- int left = max( 0, xLoc1 - range);
- int top = max( 0, yLoc1 - range);
- int right = min( MAX_WORLD_X_LOC-1, xLoc2 + range);
- int bottom = min( MAX_WORLD_Y_LOC-1, yLoc2 + range);
- // ----- mark the visit_level of the square around the unit ------//
- for( int yLoc=top ; yLoc<=bottom ; yLoc++ )
- {
- Location *locPtr = get_loc(left, yLoc);
- for( int xLoc=left ; xLoc<=right ; xLoc++, locPtr++ )
- {
- locPtr->set_visited();
- }
- }
- // ----- visit_level decreasing outside the visible range ------//
- if( extend > 0)
- {
- int visitLevel = FULL_VISIBILITY;
- int levelDrop = (FULL_VISIBILITY - EXPLORED_VISIBILITY) / (extend+1);
- xLoc1 -= range;
- xLoc2 += range;
- yLoc1 -= range;
- yLoc2 += range;
- for( ++range; extend > 0; --extend, ++range)
- {
- xLoc1--;
- xLoc2++;
- yLoc1--;
- yLoc2++;
- visitLevel -= levelDrop;
- visit_shell(xLoc1, yLoc1, xLoc2, yLoc2, visitLevel);
- }
- }
- }
- }
- // ------- End of function World::visit -----------//
- // ------- Begin of function World::visit_shell -----------//
- // set specific visit_level on the surrounding unit, town and firm
- void World::visit_shell(int xLoc1, int yLoc1, int xLoc2, int yLoc2, int visitLevel)
- {
- int left = max( 0, xLoc1 );
- int top = max( 0, yLoc1 );
- int right = min( MAX_WORLD_X_LOC-1, xLoc2);
- int bottom = min( MAX_WORLD_Y_LOC-1, yLoc2);
- // ------- top side ---------//
- if( yLoc1 >= 0)
- {
- Location *locPtr = get_loc( left, yLoc1);
- for( int x = left; x <= right; ++x, ++locPtr)
- locPtr->set_visited(visitLevel);
- }
- // ------- bottom side ---------//
- if( yLoc2 < max_y_loc)
- {
- Location *locPtr = get_loc( left, yLoc2);
- for( int x = left; x <= right; ++x, ++locPtr)
- locPtr->set_visited(visitLevel);
- }
- // ------- left side -----------//
- if( xLoc1 >= 0)
- {
- for( int y = top; y <= bottom; ++y)
- {
- get_loc(xLoc1,y)->set_visited(visitLevel);
- }
- }
- // ------- right side -----------//
- if( xLoc2 < max_x_loc)
- {
- for( int y = top; y <= bottom; ++y)
- {
- get_loc(xLoc2,y)->set_visited(visitLevel);
- }
- }
- }
- // ------- End of function World::visit_shell -----------//
- //------- Begin of function World::process_visibility -----------//
- void World::process_visibility()
- {
- if( config.fog_of_war )
- {
- // ###### begin Gilbert 13/10 ########//
- //for( int y = 0; y < max_y_loc; ++y)
- //{
- // Location *locPtr = get_loc(0,y);
- // for( int x = 0; x < max_x_loc; ++x, ++locPtr)
- // {
- // locPtr->dec_visibility();
- // }
- //}
-
- int count = max_x_loc * max_y_loc;
- const int sizeOfLoc = sizeof(Location);
- unsigned char *locVisitLevel = &get_loc(0,0)->visit_level;
- unsigned char decVisitLevel = EXPLORED_VISIBILITY*2+1;
- /* Original Visual C++ assembly code for reference
- _asm
- {
- mov ecx, count
- mov ebx, locVisitLevel
- mov edx, sizeOfLoc
- mov ah, decVisitLevel
- process_visit_level_1:
- mov al,[ebx]
- cmp al,ah // if(al > EXPLORED_VISIBILITY*2) al--;
- cmc
- sbb al,0
- mov [ebx],al
- add ebx, edx
- loop process_visit_level_1
- }
- */
- __asm__ __volatile__ (
- "movb %0, %%ah\n"
- "process_visit_level_1:\n\t"
- "movb (%%ebx), %%al\n\t"
- "cmpb %%ah, %%al\n\t"
- "cmc\n\t"
- "sbbb $0, %%al\n\t"
- "movb %%al, (%%ebx)\n\t"
- "addl %%edx, %%ebx\n\t"
- "loop process_visit_level_1\n\t"
- :
- : "m"(decVisitLevel), "b"(locVisitLevel), "c"(count), "d"(sizeOfLoc)
- : "%eax"
- );
- // ###### end Gilbert 13/10 ########//
- }
- }
- //------- End of function World::process_visibility -----------//
- //--------- Begin of function World::disp_next --------//
- //
- // Display the next object of the same type.
- //
- // <int> seekDir : -1 - display the previous one in the list.
- // 1 - display the next one in the list.
- //
- // <int> sameNation - whether display the next object of the same
- // nation only or of any nation.
- //
- void World::disp_next(int seekDir, int sameNation)
- {
- //--- if the selected one is a unit ----//
- if( unit_array.selected_recno )
- {
- int unitRecno = unit_array.selected_recno;
- Unit* unitPtr = unit_array[unit_array.selected_recno];
- int unitClass = unit_res[unitPtr->unit_id]->unit_class;
- int nationRecno = unitPtr->nation_recno;
- while(1)
- {
- if( seekDir < 0 )
- {
- unitRecno--;
- if( unitRecno < 1 )
- unitRecno = unit_array.size();
- }
- else
- {
- unitRecno++;
- if( unitRecno > unit_array.size() )
- unitRecno = 1;
- }
- if( unit_array.is_deleted(unitRecno) )
- continue;
- unitPtr = unit_array[unitRecno];
- if( !unitPtr->is_visible() )
- continue;
- //--- check if the location of the unit has been explored ---//
- if( !world.get_loc(unitPtr->next_x_loc(), unitPtr->next_y_loc())->explored() )
- continue;
- //-------- if are of the same nation --------//
- if( sameNation && unitPtr->nation_recno != nationRecno )
- continue;
- //---------------------------------//
- if( unit_res[unitPtr->unit_id]->unit_class == unitClass )
- {
- power.reset_selection();
- unitPtr->selected_flag = 1;
- unit_array.selected_recno = unitRecno;
- unit_array.selected_count++;
- world.go_loc( unitPtr->cur_x_loc(), unitPtr->cur_y_loc() );
- return;
- }
- //--- if the recno loops back to the starting one ---//
- if( unitRecno == unit_array.selected_recno )
- break;
- }
- }
- //--- if the selected one is a firm ----//
- if( firm_array.selected_recno )
- {
- int firmRecno = firm_array.selected_recno;
- Firm* firmPtr = firm_array[firm_array.selected_recno];
- int firmId = firmPtr->firm_id;
- int nationRecno = firmPtr->nation_recno;
- while(1)
- {
- if( seekDir < 0 )
- {
- firmRecno--;
- if( firmRecno < 1 )
- firmRecno = firm_array.size();
- }
- else
- {
- firmRecno++;
- if( firmRecno > firm_array.size() )
- firmRecno = 1;
- }
- if( firm_array.is_deleted(firmRecno) )
- continue;
- firmPtr = firm_array[firmRecno];
- //-------- if are of the same nation --------//
- if( sameNation && firmPtr->nation_recno != nationRecno )
- continue;
- //--- check if the location of this firm has been explored ---//
- if( !world.get_loc(firmPtr->center_x, firmPtr->center_y)->explored() )
- continue;
- //---------------------------------//
- if( firmPtr->firm_id == firmId )
- {
- power.reset_selection();
- firm_array.selected_recno = firmRecno;
- world.go_loc( firmPtr->center_x, firmPtr->center_y );
- return;
- }
- //--- if the recno loops back to the starting one ---//
- if( firmRecno == firm_array.selected_recno )
- break;
- }
- }
- //--- if the selected one is a town ----//
- if( town_array.selected_recno )
- {
- int townRecno = town_array.selected_recno;
- int nationRecno = town_array[townRecno]->nation_recno;
- Town* townPtr;
- while(1)
- {
- if( seekDir < 0 )
- {
- townRecno--;
- if( townRecno < 1 )
- townRecno = town_array.size();
- }
- else
- {
- townRecno++;
- if( townRecno > town_array.size() )
- townRecno = 1;
- }
- if( town_array.is_deleted(townRecno) )
- continue;
- townPtr = town_array[townRecno];
- //-------- if are of the same nation --------//
- if( sameNation && townPtr->nation_recno != nationRecno )
- continue;
- //--- check if the location of this town has been explored ---//
- if( !world.get_loc(townPtr->center_x, townPtr->center_y)->explored() )
- continue;
- //---------------------------------//
- power.reset_selection();
- town_array.selected_recno = townRecno;
- world.go_loc( townPtr->center_x, townPtr->center_y );
- return;
- //--- if the recno loops back to the starting one ---//
- if( townRecno == town_array.selected_recno )
- break;
- }
- }
- //--- if the selected one is a natural resource site ----//
- if( site_array.selected_recno )
- {
- int siteRecno = site_array.selected_recno;
- Site* sitePtr = site_array[site_array.selected_recno];
- int siteType = sitePtr->site_type;
- while(1)
- {
- if( seekDir < 0 )
- {
- siteRecno--;
- if( siteRecno < 1 )
- siteRecno = site_array.size();
- }
- else
- {
- siteRecno++;
- if( siteRecno > site_array.size() )
- siteRecno = 1;
- }
- if( site_array.is_deleted(siteRecno) )
- continue;
- sitePtr = site_array[siteRecno];
- //--- check if the location of this site has been explored ---//
- if( !world.get_loc(sitePtr->map_x_loc, sitePtr->map_y_loc)->explored() )
- continue;
- //---------------------------------//
- if( sitePtr->site_type == siteType )
- {
- power.reset_selection();
- site_array.selected_recno = siteRecno;
- world.go_loc( sitePtr->map_x_loc, sitePtr->map_y_loc );
- return;
- }
- //--- if the recno loops back to the starting one ---//
- if( siteRecno == site_array.selected_recno )
- break;
- }
- }
- }
- //----------- End of function World::disp_next --------//
- #ifdef DEBUG3
- //--------- Begin of function World::get_loc --------//
- //
- Location* World::get_loc(int xLoc, int yLoc)
- {
- err_when( xLoc<0 || xLoc>=MAX_WORLD_X_LOC );
- err_when( yLoc<0 || yLoc>=MAX_WORLD_Y_LOC );
- return loc_matrix + MAX_WORLD_X_LOC * yLoc + xLoc;
- }
- //----------- End of function World::get_loc --------//
- //--------- Begin of function World::get_region_id --------//
- //
- BYTE World::get_region_id(int xLoc, int yLoc)
- {
- err_when( xLoc<0 || xLoc>=MAX_WORLD_X_LOC );
- err_when( yLoc<0 || yLoc>=MAX_WORLD_Y_LOC );
- return loc_matrix[MAX_WORLD_X_LOC*yLoc+xLoc].region_id;
- }
- //----------- End of function World::get_region_id --------//
- #endif
- // ####### begin Gilbert 25/7 #########//
- // return true if any location adjacent to (x,y) is on a particular region
- int World::is_adjacent_region(int x, int y, int regionId)
- {
- if( y > 0 )
- {
- if( x > 0 )
- {
- if( get_region_id(x-1,y-1) == regionId )
- return 1;
- }
- if( get_region_id(x,y-1) == regionId )
- return 1;
- if( x < max_x_loc-1 )
- {
- if( get_region_id(x+1,y-1) == regionId )
- return 1;
- }
- }
- if( x > 0 )
- {
- if( get_region_id(x-1,y) == regionId )
- return 1;
- }
- if( x < max_x_loc-1 )
- {
- if( get_region_id(x+1,y) == regionId )
- return 1;
- }
- if( y < max_y_loc-1)
- {
- if( x > 0 )
- {
- if( get_region_id(x-1,y+1) == regionId )
- return 1;
- }
- if( get_region_id(x,y+1) == regionId )
- return 1;
- if( x < max_x_loc-1 )
- {
- if( get_region_id(x+1,y+1) == regionId )
- return 1;
- }
- }
- return 0;
- }
- // ####### end Gilbert 25/7 #########//
|