123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838 |
- /*
- * 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 : OUNITA.CPP
- //Description : Object UnitArray
- #include <ALL.h>
- #include <OVGA.h>
- #include <OSYS.h>
- #include <OSTR.h>
- #include <OSPY.h>
- #include <OREMOTE.h>
- #include <ONATION.h>
- #include <OREBEL.h>
- #include <OGODRES.h>
- #include <OUNITALL.h>
- #include <OWORLD.h>
- #include <OCONFIG.h>
- #include <OGAME.h>
- #include <OANLINE.h>
- #include <OFONT.h>
- #include <CRC.h>
- #ifdef NO_DEBUG_UNIT
- #undef err_when
- #undef err_here
- #undef err_if
- #undef err_else
- #undef err_now
- #define err_when(cond)
- #define err_here()
- #define err_if(cond)
- #define err_else
- #define err_now(msg)
- #undef DEBUG
- #endif
- //--------- Declare static functions ---------//
- static void put_profile(int y, char* dispDes, int dispValue);
- //--------- Begin of function UnitArray::UnitArray ---------//
- //
- // <int> initArraySize - the initial size of this array.
- //
- UnitArray::UnitArray(int initArraySize) : SpriteArray(initArraySize)
- {
- }
- //----------- End of function UnitArray::UnitArray -----------//
- //--------- Begin of function UnitArray::init ---------//
- //
- void UnitArray::init()
- {
- //-------- initialize group selection parameter -------//
- cur_group_id = 1;
- cur_team_id = 1;
- selected_land_unit_count = 0;
- selected_sea_unit_count = 0;
- selected_air_unit_count = 0;
- idle_blocked_unit_reset_count = 0;
- selected_land_unit_array = NULL;
- selected_sea_unit_array = NULL;
- selected_air_unit_array = NULL;
- visible_unit_count = 0;
- mp_first_frame_to_select_caravan = 0;
- mp_first_frame_to_select_ship = 0;
- mp_pre_selected_caravan_recno = 0;
- mp_pre_selected_ship_recno = 0;
- //------------ init sprite_array ------------//
- SpriteArray::init();
- }
- //----------- End of function UnitArray::init -----------//
- //--------- Begin of function UnitArray::add_unit ---------//
- //
- // <int> unitId - the id. of the unit
- // <int> nationRecno - the recno of the nation that the unit belongs to
- // [int] rankId - rank id. of the unit (none for non-human unit)
- // [int] unitLoyalty - loyalty of the unit (none for non-human unit)
- // [int] startXLoc, startYLoc - the starting location of the unit
- // (if startXLoc < 0, this is a unit for hire, and is not a unit of the game yet. init_sprite() won't be called for this unit)
- // (default: -1, -1)
- // [int] remoteAction - whether this is a remote action or not.
- //
- // return : <int> - the recno of the unit added.
- //
- int UnitArray::add_unit(int unitId, int nationRecno, int rankId, int unitLoyalty, int startXLoc, int startYLoc)
- {
- //-------- create and initialize Unit -------//
- Unit* unitPtr = create_unit(unitId);
- //----------- add to SpriteArray ------------//
- unitPtr->init(unitId, nationRecno, rankId, unitLoyalty, startXLoc, startYLoc);
- //-------------------------------------------//
- return unitPtr->sprite_recno;
- }
- //----------- End of function UnitArray::add_unit -----------//
- //-------- Begin of function UnitArray::create_unit --------//
- //
- Unit* UnitArray::create_unit(int unitId)
- {
- Unit* unitPtr;
- UnitInfo* unitInfo = unit_res[unitId];
- switch(unitId)
- {
- case UNIT_CARAVAN:
- unitPtr = new UnitCaravan;
- break;
- case UNIT_VESSEL:
- case UNIT_TRANSPORT:
- case UNIT_CARAVEL:
- case UNIT_GALLEON:
- unitPtr = new UnitMarine;
- break;
- case UNIT_EXPLOSIVE_CART:
- unitPtr = new UnitExpCart;
- break;
- default:
- if( unitInfo->is_monster )
- unitPtr = new UnitMonster;
- else if( unitInfo->solider_id ) // if it is a vehicle unit
- unitPtr = new UnitVehicle;
- else if( god_res.is_god_unit(unitId) )
- unitPtr = new UnitGod;
- else
- unitPtr = new Unit;
- }
- SpriteArray::add(unitPtr); // it set Sprite::sprite_recno
- return unitPtr;
- }
- //----------- End of function UnitArray::create_unit ---------//
- //-------- Begin of function UnitArray::unit_class_size --------//
- //
- // Return the size of the class.
- //
- int UnitArray::unit_class_size(int unitId)
- {
- UnitInfo* unitInfo = unit_res[unitId];
- switch(unitId)
- {
- case UNIT_CARAVAN:
- return sizeof(UnitCaravan);
- case UNIT_VESSEL:
- case UNIT_TRANSPORT:
- case UNIT_CARAVEL:
- case UNIT_GALLEON:
- return sizeof(UnitMarine);
- case UNIT_EXPLOSIVE_CART:
- return sizeof(UnitExpCart);
- default:
- if( unitInfo->is_monster )
- return sizeof(UnitMonster);
- else if( unitInfo->solider_id ) // if it is a vehicle unit
- return sizeof(UnitVehicle);
- else if( god_res.is_god_unit(unitId) )
- return sizeof(UnitGod);
- else
- return sizeof(Unit);
- }
- }
- //----------- End of function UnitArray::unit_class_size ---------//
- //-------- Begin of function UnitArray::disappear_in_town --------//
- //
- // The unit disappear from the map because it has moved into a town.
- //
- void UnitArray::disappear_in_town(int unitRecno, int townRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL )
- rebel_array.settle_town(unitRecno, townRecno);
- del(unitRecno); // delete it from unit_array
- }
- //----------- End of function UnitArray::disappear_in_town ---------//
- //-------- Begin of function UnitArray::disappear_in_firm --------//
- //
- // The unit disappear from the map because it has moved into a town.
- //
- void UnitArray::disappear_in_firm(int unitRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- err_when( unitPtr->unit_mode == UNIT_MODE_REBEL ); // this shouldn't happen
- del(unitRecno); // delete it from unit_array
- }
- //----------- End of function UnitArray::disappear_in_firm ---------//
- //-------- Begin of function UnitArray::die --------//
- //
- void UnitArray::die(int unitRecno)
- {
- Unit* unitPtr = unit_array[unitRecno];
- if( unitPtr->unit_mode == UNIT_MODE_REBEL )
- rebel_array.drop_rebel_identity(unitRecno);
- unitPtr->die();
- del(unitRecno); // delete it from unit_array
- }
- //----------- End of function UnitArray::die ---------//
- //--------- Begin of function UnitArray::draw_dot ---------//
- //
- // Draw 2x2 tiny squares on map window representing the location of the unit ---//
- //
- void UnitArray::draw_dot()
- {
- char* vgaBufPtr = vga_back.buf_ptr();
- char* writePtr;
- int i, j, mapX, mapY;
- Unit* unitPtr;
- char* nationColorArray = nation_array.nation_color_array;
- char nationColor;
- int vgaBufPitch = vga_back.buf_pitch();
- const unsigned int excitedColorCount = 4;
- char excitedColorArray[MAX_NATION+1][excitedColorCount];
- short playerNationRecno = nation_array.player_recno;
- short lineFromX, lineFromY, lineToX, lineToY;
- int resultNodeRecno, resultNodeCount;
- ResultNode *resultNode1, *resultNode2;
- for( i = 0; i <= MAX_NATION; ++i )
- {
- if( i == 0 || !nation_array.is_deleted(i) )
- {
- char *remapTable = game.get_color_remap_table(i, 0);
- excitedColorArray[i][0] = remapTable[0xe0];
- excitedColorArray[i][1] = remapTable[0xe1];
- excitedColorArray[i][2] = remapTable[0xe2];
- excitedColorArray[i][3] = remapTable[0xe3];
- }
- else
- {
- excitedColorArray[i][0] =
- excitedColorArray[i][1] =
- excitedColorArray[i][2] =
- excitedColorArray[i][3] = (char) V_WHITE;
- }
- }
- int arraySize = size();
- int lineColor;
- //### begin alex 27/10 ###//
- //------------- set boundary of anim_line to mini-map ------------//
- short animLineBoundX1 = anim_line.bound_x1;
- short animLineBoundY1 = anim_line.bound_y1;
- short animLineBoundX2 = anim_line.bound_x2;
- short animLineBoundY2 = anim_line.bound_y2;
- anim_line.bound_x1 = MAP_X1;
- anim_line.bound_y1 = MAP_Y1;
- anim_line.bound_x2 = MAP_X2;
- anim_line.bound_y2 = MAP_Y2;
- //#### end alex 27/10 ####//
- for(i=1; i<=arraySize; i++)
- {
- unitPtr = (Unit*)get_ptr(i);
- if( !unitPtr || !unitPtr->is_visible() || unitPtr->is_shealth())
- continue;
- if( unitPtr->mobile_type == UNIT_SEA )
- lineColor = V_WHITE;
- else
- lineColor = V_BLACK;
- //---------------- draw unit path in mini_map ------------//
- if(unitPtr->selected_flag && (config.show_unit_path & 2) )
- {
- //#ifdef DEBUG
- //if(config.show_ai_info || unitPtr->nation_recno==playerNationRecno)
- //#else
- //if(unitPtr->nation_recno==playerNationRecno)
- //#endif
- if( config.show_ai_info || !playerNationRecno || unitPtr->is_nation(playerNationRecno) )
- {
- resultNodeRecno = unitPtr->result_node_recno;
- resultNodeCount = unitPtr->result_node_count;
- if(resultNodeCount && resultNodeRecno<=resultNodeCount)
- {
- //-----------------------------------------------------------//
- if(unitPtr->cur_x_loc()!=unitPtr->go_x_loc() || unitPtr->cur_y_loc()!=unitPtr->go_y_loc())
- {
- lineFromX = MAP_X1 + unitPtr->go_x_loc();
- lineFromY = MAP_Y1 + unitPtr->go_y_loc();
- lineToX = MAP_X1 + unitPtr->next_x_loc();
- lineToY = MAP_Y1 + unitPtr->next_y_loc();
- vga_back.line(lineFromX, lineFromY, lineToX, lineToY, lineColor);
- }
- //-----------------------------------------------------------//
- err_when(resultNodeRecno<1);
- resultNode1 = unitPtr->result_node_array + resultNodeRecno - 1;
- resultNode2 = resultNode1 + 1;
- for(j=resultNodeRecno+1; j<=resultNodeCount; j++, resultNode1++, resultNode2++)
- {
- lineFromX = MAP_X1 + resultNode2->node_x;
- lineFromY = MAP_Y1 + resultNode2->node_y;
- lineToX = MAP_X1 + resultNode1->node_x;
- lineToY = MAP_Y1 + resultNode1->node_y;
- vga_back.line(lineFromX, lineFromY, lineToX, lineToY, lineColor);
- }
- }
- //### begin alex 27/10 ###//
- //-------------- draw way_point on mini map ------------//
- if(unitPtr->way_point_count>1)
- {
- resultNode1 = unitPtr->way_point_array;
- resultNode2 = resultNode1+1;
- lineToX = MAP_X1 + resultNode1->node_x;
- lineToY = MAP_Y1 + resultNode1->node_y;
- for(j=unitPtr->way_point_count-1; j>0; j--, resultNode1++, resultNode2++)
- {
- lineFromX = MAP_X1 + resultNode2->node_x;
- lineFromY = MAP_Y1 + resultNode2->node_y;
- anim_line.draw_line(&vga_back, lineFromX, lineFromY, lineToX, lineToY, 0, 2);
- lineToX = lineFromX;
- lineToY = lineFromY;
- }
- }
- //#### end alex 27/10 ####//
- }
- }
- }
- //### begin alex 27/10 ###//
- //---------------- restore boundary setting of anim_line --------------//
- anim_line.bound_x1 = animLineBoundX1;
- anim_line.bound_y1 = animLineBoundY1;
- anim_line.bound_x2 = animLineBoundX2;
- anim_line.bound_y2 = animLineBoundY2;
- //#### end alex 27/10 ####//
- for(i=1; i<=arraySize; i++)
- {
- unitPtr = (Unit*)get_ptr(i);
- if( !unitPtr || !unitPtr->is_visible() || unitPtr->is_shealth())
- continue;
- mapX = MAP_X1 + unitPtr->cur_x_loc();
- mapY = MAP_Y1 + unitPtr->cur_y_loc();
- if( mapX == MAP_WIDTH-1 )
- mapX = MAP_WIDTH-2;
- if( mapY == MAP_HEIGHT-1 )
- mapY = MAP_HEIGHT-2;
- writePtr = vgaBufPtr + mapY*vgaBufPitch + mapX;
- nationColor = unitPtr->cur_action != SPRITE_ATTACK ?
- nationColorArray[unitPtr->nation_recno] :
- excitedColorArray[unitPtr->nation_recno][sys.frame_count % excitedColorCount];
- // ###### begin Gilbert 3/11 #######//
- int dotSize = unitPtr->mobile_type == UNIT_LAND ? 2 : 3;
- if( dotSize == 2 )
- {
- if( writePtr[0] != UNEXPLORED_COLOR )
- writePtr[0] = nationColor;
- if( writePtr[1] != UNEXPLORED_COLOR )
- writePtr[1] = nationColor;
- if( writePtr[vgaBufPitch] != UNEXPLORED_COLOR )
- writePtr[vgaBufPitch] = nationColor;
- if( writePtr[vgaBufPitch+1] != UNEXPLORED_COLOR )
- writePtr[vgaBufPitch+1] = nationColor;
- }
- else if( dotSize == 3 )
- {
- if( writePtr[-vgaBufPitch-1] != UNEXPLORED_COLOR )
- writePtr[-vgaBufPitch-1] = nationColor;
- if( writePtr[-vgaBufPitch] != UNEXPLORED_COLOR )
- writePtr[-vgaBufPitch] = nationColor;
- if( writePtr[-vgaBufPitch+1] != UNEXPLORED_COLOR )
- writePtr[-vgaBufPitch+1] = nationColor;
- if( writePtr[-1] != UNEXPLORED_COLOR )
- writePtr[-1] = nationColor;
- if( writePtr[0] != UNEXPLORED_COLOR )
- writePtr[0] = nationColor;
- if( writePtr[1] != UNEXPLORED_COLOR )
- writePtr[1] = nationColor;
- if( writePtr[vgaBufPitch-1] != UNEXPLORED_COLOR )
- writePtr[vgaBufPitch-1] = nationColor;
- if( writePtr[vgaBufPitch] != UNEXPLORED_COLOR )
- writePtr[vgaBufPitch] = nationColor;
- if( writePtr[vgaBufPitch+1] != UNEXPLORED_COLOR )
- writePtr[vgaBufPitch+1] = nationColor;
- }
- // ###### end Gilbert 3/11 #######//
- }
- }
- //----------- End of function UnitArray::draw_dot -----------//
- //--------- Begin of function UnitArray::draw_profile ---------//
- void UnitArray::draw_profile()
- {
- #ifdef DEBUG
- static unsigned long lastDrawTime = m.get_time();
- if(m.get_time() >= lastDrawTime + 1000)
- {
- //--------- update unit process profile ---------//
- last_unit_ai_profile_time = unit_ai_profile_time;
- unit_ai_profile_time = 0L;
- last_unit_profile_time = unit_profile_time;
- unit_profile_time = 0L;
- //--------- update seek path profile ---------//
- last_seek_path_profile_time = seek_path_profile_time;
- seek_path_profile_time = 0L;
- //--------- update sprite process profile --------//
- last_sprite_array_profile_time = sprite_array_profile_time;
- sprite_array_profile_time = 0L;
- //------- update sprite cur_action profile ---------//
- last_sprite_idle_profile_time = sprite_idle_profile_time;
- sprite_idle_profile_time = 0L;
- last_sprite_move_profile_time = sprite_move_profile_time;
- sprite_move_profile_time = 0L;
- last_sprite_wait_profile_time = sprite_wait_profile_time;
- sprite_wait_profile_time = 0L;
- last_sprite_attack_profile_time = sprite_attack_profile_time;
- sprite_attack_profile_time = 0L;
- last_unit_attack_profile_time = unit_attack_profile_time;
- unit_attack_profile_time = 0L;
- last_unit_assign_profile_time = unit_assign_profile_time;
- unit_assign_profile_time = 0L;
- lastDrawTime = m.get_time();
- }
- //------------ draw unit process profile -------------//
- int y=ZOOM_Y1+120;
- put_profile(y , "Unit AI:" , last_unit_ai_profile_time );
- put_profile(y+=20, "Unit:" , last_unit_profile_time );
- put_profile(y+=20, "Sprite:" , last_sprite_array_profile_time );
- put_profile(y+=20, "SeekPath:" , last_seek_path_profile_time );
- put_profile(y+=20, "Sprite Idle:" , last_sprite_idle_profile_time );
- put_profile(y+=20, "Sprite Move:" , last_sprite_move_profile_time );
- put_profile(y+=20, "Sprite Wait:" , last_sprite_wait_profile_time );
- put_profile(y+=20, "Sprite Attack:" , last_sprite_attack_profile_time );
- put_profile(y+=20, "Unit Attack:" , last_unit_attack_profile_time );
- put_profile(y+=20, "Unit Assign:" , last_unit_assign_profile_time );
- #endif
- }
- //----------- End of function UnitArray::draw_profile -----------//
- //--------- Begin of static function put_profile ---------//
- //
- static void put_profile(int y, char* dispDes, int dispValue)
- {
- font_news.put( ZOOM_X1+10, y, dispDes );
- font_news.put( ZOOM_X1+120, y, dispValue );
- }
- //----------- End of static function put_profile -----------//
- //--------- Begin of function UnitArray::process ---------//
- //
- // This function is called every frame.
- //
- void UnitArray::process()
- {
- #define SYS_YIELD_INTERVAL 50
- #define YEAR_FRAME_COUNT 365*FRAMES_PER_DAY // choose a value that is multiply of FRAMES_PER_DAY
- Unit* unitPtr;
- int i;
- int arraySize = size();
- int sysFrameCount = int(sys.frame_count%FRAMES_PER_DAY);
- int yearFrameCount = int(sys.frame_count%YEAR_FRAME_COUNT);
- int compareI = arraySize%FRAMES_PER_DAY;
- if(compareI < sysFrameCount)
- compareI += FRAMES_PER_DAY;
- int sysYieldCount = arraySize - arraySize%SYS_YIELD_INTERVAL;
- for(i=arraySize; i; --i, compareI--) // for(i=arraySize; i>0; --i, compareI++) or //for(i=1; i<=arraySize; i++, compareI++)
- {
- //-------- system yield ---------//
- if(i==sysYieldCount)
- {
- sysYieldCount -= SYS_YIELD_INTERVAL;
- sys.yield();
- }
- //-------------------------------//
- if(compareI == sysFrameCount)
- {
- compareI += FRAMES_PER_DAY;
- if( is_deleted(i) )
- continue;
- unitPtr = (Unit*) get_ptr(i);
- //-------------- reset ignore_power_nation ------------//
- if(compareI==yearFrameCount && unitPtr->unit_id!=UNIT_CARAVAN)
- unitPtr->ignore_power_nation = 0;
- unitPtr->next_day(); // although this function is called every frame, next_day() & process_ai() is only called once per day
- if( is_deleted(i) )
- continue;
- #ifdef DEBUG
- if(config.disable_ai_flag==0 && unitPtr->ai_unit)
- #else
- if( unitPtr->ai_unit )
- #endif
- {
- #ifdef DEBUG
- unsigned long profileAiStartTime = m.get_time();
- #endif
-
- unitPtr->process_ai();
- #ifdef DEBUG
- unit_ai_profile_time += m.get_time() - profileAiStartTime;
- #endif
- }
- //----- if it's an independent unit -------//
- else if( !unitPtr->nation_recno && unitPtr->race_id && !unitPtr->spy_recno)
- unitPtr->think_independent_unit();
- }
- }
- if(idle_blocked_unit_reset_count<50)
- idle_blocked_unit_reset_count++; // the ability to restart idle blocked attacking unit
- //------- process Sprite ---------//
- SpriteArray::process();
- }
- //----------- End of function UnitArray::process -----------//
- //--------- Begin of function UnitArray::update_selected_trade_unit_info ---------//
- // update trade information of trading units if these units are selected
- //
- void UnitArray::update_selected_trade_unit_info()
- {
- short playerNationRecno = nation_array.player_recno;
- Unit *unitPtr;
- UnitMarine *marinePtr;
- if(remote.is_enable())
- {
- for(int i=size(); i>0; --i)
- {
- if(is_deleted(i))
- continue;
- unitPtr = (Unit*)get_ptr(i);
- if(!unitPtr->is_visible())
- continue;
- switch(unitPtr->unit_id)
- {
- case UNIT_CARAVAN:
- if(mp_is_selected_caravan(i))
- ((UnitCaravan*) unitPtr)->update_stop_and_goods_info();
- break;
- case UNIT_VESSEL: case UNIT_CARAVEL: case UNIT_GALLEON:
- marinePtr = ((UnitMarine*) unitPtr);
- if(marinePtr->auto_mode && mp_is_selected_ship(i))
- marinePtr->update_stop_and_goods_info();
- break;
- default: break;
- }
- }
- }
- else if(selected_recno && !is_deleted(selected_recno))
- {
- unitPtr = (Unit*)get_ptr(selected_recno);
- if(unitPtr->nation_recno==playerNationRecno || config.show_ai_info)
- {
- switch(unitPtr->unit_id)
- {
- case UNIT_CARAVAN:
- ((UnitCaravan*) unitPtr)->update_stop_and_goods_info();
- break;
- case UNIT_VESSEL: case UNIT_CARAVEL: case UNIT_GALLEON:
- marinePtr = ((UnitMarine*) unitPtr);
- if(marinePtr->auto_mode)
- marinePtr->update_stop_and_goods_info();
- break;
- default:
- break;
- }
- }
- }
- }
- //----------- End of function UnitArray::update_selected_trade_unit_info -----------//
- //----------- Begin of function UnitArray::return_camp -----------//
- //
- // Order all units that are currently selected to return to their
- // home camp.
- //
- void UnitArray::return_camp(int remoteAction, short *selectedUnitArray, int selectedCount)
- {
- Unit* unitPtr;
- if( !selectedUnitArray )
- {
- if( !remoteAction && remote.is_enable() )
- {
- selectedCount = 0;
- int i;
- for( i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = this->operator[](i);
- if( !unitPtr->selected_flag || !unitPtr->is_visible() )
- continue;
- if(unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE)
- continue;
- if( !unitPtr->is_own() ) // only if the unit belongs to us (a spy is also okay if true_nation_recno is ours)
- continue;
- //---------------------------------//
- if( unitPtr->home_camp_firm_recno )
- selectedCount++;
- }
- // packet structure : <no. of units> <unit recno>...
- short *shortPtr = (short *) remote.new_send_queue_msg(MSG_UNITS_RETURN_CAMP, (1+selectedCount)*sizeof(short) );
- *shortPtr = selectedCount;
- shortPtr++;
- int reCount = 0;
- for( i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = this->operator[](i);
- if( !unitPtr->selected_flag || !unitPtr->is_visible() )
- continue;
- if(unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE)
- continue;
- if( !unitPtr->is_own() ) // only if the unit belongs to us (a spy is also okay if true_nation_recno is ours)
- continue;
- //---------------------------------//
- if( unitPtr->home_camp_firm_recno )
- {
- err_when( reCount > selectedCount );
- *shortPtr = i;
- shortPtr++;
- reCount++;
- }
- }
- err_when( reCount != selectedCount );
- return;
- }
- else
- {
- for( int i=unit_array.size() ; i>0 ; i-- )
- {
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = this->operator[](i);
- if( !unitPtr->selected_flag || !unitPtr->is_visible() )
- continue;
- if(unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE)
- continue;
- if( !unitPtr->is_own() ) // only if the unit belongs to us (a spy is also okay if true_nation_recno is ours)
- continue;
- //---------------------------------//
- if( unitPtr->home_camp_firm_recno )
- unitPtr->return_camp();
- }
- }
- }
- else
- {
- if( !remoteAction && remote.is_enable() )
- {
- if( selectedCount > 0)
- {
- // packet structure : <no. of units> <unit recno>...
- short *shortPtr = (short *) remote.new_send_queue_msg(MSG_UNITS_RETURN_CAMP, (1+selectedCount)*sizeof(short) );
- *shortPtr = selectedCount;
- shortPtr++;
- memcpy(shortPtr, selectedUnitArray, sizeof(short)*selectedCount );
- }
- return;
- }
- else
- {
- for( int j = selectedCount-1; j >= 0; j--)
- {
- // descending unit recno
- int i = selectedUnitArray[j];
- if( unit_array.is_deleted(i) )
- continue;
- unitPtr = this->operator[](i);
- if( !unitPtr->is_visible() )
- continue;
- if(unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE)
- continue;
- //---------------------------------//
- if( unitPtr->home_camp_firm_recno )
- unitPtr->return_camp();
- }
- }
- }
- }
- //----------- End of function UnitArray::return_camp -----------//
- #ifdef DEBUG
- //------- Begin of function UnitArray::operator[] -----//
- Unit* UnitArray::operator[](int recNo)
- {
- Unit* unitPtr = (Unit*) get_ptr(recNo);
- if( !unitPtr )
- err.run( "UnitArray[] is deleted" );
- return unitPtr;
- }
- //--------- End of function UnitArray::operator[] ----//
- #endif
- //------- Begin of function UnitArray::is_deleted -----//
- int UnitArray::is_deleted(int recNo)
- {
- Unit *unitPtr = (Unit*) get_ptr(recNo);
- if( !unitPtr )
- return 1;
- if( unitPtr->hit_points<=0 || unitPtr->cur_action==SPRITE_DIE || unitPtr->action_mode==ACTION_DIE )
- return 1;
-
- return 0;
- }
- //--------- End of function UnitArray::is_deleted ----//
- //------- Begin of function UnitArray::is_truly_deleted -----//
- int UnitArray::is_truly_deleted(int recNo)
- {
- return get_ptr(recNo) == NULL;
- }
- //--------- End of function UnitArray::is_truly_deleted ----//
|