//--------- Begin of function Sprite::process_turn --------// void Sprite::process_turn() { err_when(!sprite_info->need_turning); match_dir(); if(is_dir_correct()) cur_action = SPRITE_MOVE; }
//--------- Begin of function Unit::process_ship_to_beach ---------// // process unit action SHIP_TO_BEACH // void Unit::process_ship_to_beach() { //----- action_mode never clear, in_beach to skip idle checking if(cur_action==SPRITE_IDLE) { int shipXLoc = next_x_loc(); int shipYLoc = next_y_loc(); if(shipXLoc==move_to_x_loc && shipYLoc==move_to_y_loc) { if(abs(move_to_x_loc-action_x_loc2)<=2 && abs(move_to_y_loc-action_y_loc2)<=2) { UnitMarine *shipPtr = (UnitMarine*) this; //------------------------------------------------------------------------------// // determine whether extra_move is required //------------------------------------------------------------------------------// switch(shipPtr->extra_move_in_beach) { case NO_EXTRA_MOVE: if(abs(shipXLoc-action_x_loc2)>1 || abs(shipYLoc-action_y_loc2)>1) { err_when(abs(shipXLoc-action_x_loc2)>2 || abs(shipYLoc-action_y_loc2)>2); err_when(result_node_array); shipPtr->extra_move(); } else { //shipPtr->in_beach = 1; shipPtr->extra_move_in_beach = NO_EXTRA_MOVE; //#### trevor 23/10 #####// if(ai_action_id) nation_array[nation_recno]->action_finished(ai_action_id, sprite_recno); //#### trevor 23/10 #####// } break; case EXTRA_MOVING_IN: case EXTRA_MOVING_OUT: //err_when(cur_action!=SPRITE_SHIP_EXTRA_MOVE); break; //#### trevor 23/10 #####// case EXTRA_MOVE_FINISH: if(ai_action_id) nation_array[nation_recno]->action_finished(ai_action_id, sprite_recno); break; //#### trevor 23/10 #####// default: err_here(); break; } } } else reset_action_para(); } else if(cur_action==SPRITE_TURN && is_dir_correct()) set_move(); }
//------ Begin of function Unit::handle_blocked_move_s11 -------// // both blocked and blocking are size 1 // void Unit::handle_blocked_move_s11(Unit *unitPtr) { err_when( world.get_unit_recno(next_x_loc(), next_y_loc(), mobile_type) != sprite_recno ); err_when( world.get_unit_recno(unitPtr->next_x_loc(), unitPtr->next_y_loc(), unitPtr->mobile_type) != unitPtr->sprite_recno ); err_when(cur_x!=next_x || cur_y!=next_y); int waitTerm; int moveStep = move_step_magn(); switch(unitPtr->cur_action) { //------------------------------------------------------------------------------------// // handle blocked for units belonging to the same nation. For those belonging to other // nations, wait for it moving to other locations or search for another path. //------------------------------------------------------------------------------------// case SPRITE_WAIT: // the blocking unit is waiting err_when(unitPtr->go_x==unitPtr->cur_x && unitPtr->go_y==unitPtr->cur_y); case SPRITE_TURN: if(unitPtr->nation_recno==nation_recno) handle_blocked_wait(unitPtr); // check for cycle wait for our nation else if(waiting_term>=MAX_WAITING_TERM_DIFF) { search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall searching waiting_term = 0; } else // wait set_wait(); return; //------------------------------------------------------------------------------------// // We know from the cur_action of the blocking unit it is moving to another locations, // the blocked unit wait for a number of terms or search again. //------------------------------------------------------------------------------------// case SPRITE_MOVE: case SPRITE_READY_TO_MOVE: case SPRITE_SHIP_EXTRA_MOVE: if(unit_id!=UNIT_CARAVAN && unitPtr->unit_id==UNIT_CARAVAN) // don't wait for caravans, and caravans don't wait for other units { search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP); } else { waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF; if(waiting_term>=waitTerm) { search_or_wait(); waiting_term = 0; } else set_wait(); } return; //------------------------------------------------------------------------------------// // handling blocked for idle unit //------------------------------------------------------------------------------------// case SPRITE_IDLE: err_when(unitPtr->result_node_array!=NULL); if(unitPtr->action_mode==ACTION_SHIP_TO_BEACH) { //----------------------------------------------------------------------// // the blocking unit is trying to move to beach, so wait a number of terms, // or call searching again //----------------------------------------------------------------------// if(abs(unitPtr->next_x_loc()-unitPtr->action_x_loc2)<=moveStep && abs(unitPtr->next_y_loc()-unitPtr->action_y_loc2)<=moveStep && terrain_res[world.get_loc(unitPtr->action_x_loc2, unitPtr->action_y_loc2)->terrain_id]->average_type !=TERRAIN_OCEAN) { if(action_mode2==ACTION_SHIP_TO_BEACH && action_x_loc2==unitPtr->action_x_loc2 && action_y_loc2==unitPtr->action_y_loc2) { int tempX, tempY; ship_to_beach(action_x_loc2, action_y_loc2, tempX, tempY); } else { waitTerm = (nation_recno==unitPtr->nation_recno) ? MAX_WAITING_TERM_SAME : MAX_WAITING_TERM_DIFF; if(waiting_term>=waitTerm) stop2(); else set_wait(); } return; } } if(unitPtr->nation_recno==nation_recno) //-------- same nation { //------------------------------------------------------------------------------------// // units from our nation //------------------------------------------------------------------------------------// if(unitPtr->unit_group_id==unit_group_id) { //--------------- from the same group -----------------// if(way_point_count && !unitPtr->way_point_count) { //------------ reset way point --------------// stop2(); reset_way_point_array(); } else if((unitPtr->next_x_loc() != move_to_x_loc || unitPtr->next_y_loc() != move_to_y_loc) && (unitPtr->cur_action==SPRITE_IDLE && unitPtr->action_mode2==ACTION_STOP)) move_to_my_loc(unitPtr); // push the blocking unit and exchange their destination else if(unitPtr->action_mode == ACTION_SETTLE) set_wait(); // wait for the settler else if(waiting_term>MAX_WAITING_TERM_SAME) { //---------- stop if wait too long ----------// terminate_move(); waiting_term = 0; } else set_wait(); } else if(unitPtr->action_mode2==ACTION_STOP) handle_blocked_by_idle_unit(unitPtr); else if(way_point_count && !unitPtr->way_point_count) { stop2(); reset_way_point_array(); } else search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode } else // different nation { //------------------------------------------------------------------------------------// // units from other nations //------------------------------------------------------------------------------------// if(unitPtr->next_x_loc() == move_to_x_loc && unitPtr->next_y_loc() == move_to_y_loc) { terminate_move(); // destination occupied by other unit if(action_mode==ACTION_ATTACK_UNIT && unitPtr->nation_recno!=nation_recno && unitPtr->sprite_recno==action_para) { err_when(action_x_loc!=unitPtr->next_x_loc() || action_y_loc!=unitPtr->next_y_loc()); err_when(action_mode2!=ACTION_ATTACK_UNIT && action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET && action_mode2!=ACTION_DEFEND_TOWN_ATTACK_TARGET && action_mode2!=ACTION_MONSTER_DEFEND_ATTACK_TARGET); err_when(action_para2!=action_para); err_when(action_x_loc!=action_x_loc2 || action_y_loc!=action_y_loc2); set_dir(next_x, next_y, unitPtr->next_x, unitPtr->next_y); if(is_dir_correct()) attack_unit(action_para); else set_turn(); cur_frame = 1; } } else search_or_stop(move_to_x_loc, move_to_y_loc, 1); // recall A* algorithm by default mode } return; //------------------------------------------------------------------------------------// // don't wait for attackers from other nations, search for another path. //------------------------------------------------------------------------------------// case SPRITE_ATTACK: //----------------------------------------------------------------// // don't wait for other nation unit, call searching again //----------------------------------------------------------------// if(nation_recno!=unitPtr->nation_recno) { search_or_stop(move_to_x_loc, move_to_y_loc, 1); return; } //------------------------------------------------------------------------------------// // for attackers owned by our commander, handled blocked case by case as follows. //------------------------------------------------------------------------------------// switch(unitPtr->action_mode) { case ACTION_ATTACK_UNIT: if(action_para && !unit_array.is_deleted(action_para)) { Unit *targetPtr = unit_array[action_para]; handle_blocked_attack_unit(unitPtr, targetPtr); } else search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_A_UNIT_IN_GROUP); break; case ACTION_ATTACK_FIRM: if(!unitPtr->action_para || firm_array.is_deleted(unitPtr->action_para)) set_wait(); else handle_blocked_attack_firm(unitPtr); break; case ACTION_ATTACK_TOWN: if(!unitPtr->action_para || town_array.is_deleted(unitPtr->action_para)) set_wait(); else handle_blocked_attack_town(unitPtr); break; case ACTION_ATTACK_WALL: if(unitPtr->action_para) set_wait(); else handle_blocked_attack_wall(unitPtr); break; case ACTION_GO_CAST_POWER: set_wait(); break; default: err_here(); break; } return; //------------------------------------------------------------------------------------// // the blocked unit can pass after the blocking unit disappears in air. //------------------------------------------------------------------------------------// case SPRITE_DIE: set_wait(); // assume this unit will not wait too long return; default: err_here(); break; } err_when(cur_x==go_x && cur_y==go_y && (cur_x!=next_x || cur_y!=next_y)); }
//--------- Begin of function UnitB::set_next --------// // // set the next coordinates to move to // // <int> newNextX, newNextY - next coordinate to move to // <int> para - used to count the result_path_dist // <int> ignoreBlockCheck - whether ignore blocking check or not // int UnitB::set_next(int newNextX, int newNextY, int para, int ignoreBlockCheck) { static char callingCount=0; int curNextXLoc = next_x_loc(); int curNextYLoc = next_y_loc(); int newNextXLoc = newNextX >> ZOOM_X_SHIFT_COUNT; int newNextYLoc = newNextY >> ZOOM_Y_SHIFT_COUNT; //------begin Juliet 14/10-----// int tempEndX = newNextXLoc+obj_loc_width()-1; int tempEndY = newNextYLoc+obj_loc_height()-1; //------end Juliet 14/10-------// short w, h, x, y; callingCount++; // this function is being called, prevent recursive calling if(curNextXLoc!=newNextXLoc || curNextYLoc!=newNextYLoc) { if(!is_dir_correct()) { set_turn(); return 1; } } //----------- blocking check ---------// if( !ignoreBlockCheck ) { int isBlocked=0; for(h=0, y=newNextYLoc; h<loc_height && !isBlocked ; h++, y++) { for(w=0, x=newNextXLoc; w<loc_width; w++, x++) { Location* locPtr = world.get_loc(x,y); if( locPtr->can_move(mobile_type) ) continue; //--- this location is occupied by the unit itself ---// if( locPtr->unit_recno(mobile_type) == sprite_recno ) continue; isBlocked = 1; break; } } if( isBlocked ) { //----- if we have already reach the destination -----// int rangeX1, rangeY1, rangeX2, rangeY2; get_object_range(move_to_loc_x, move_to_loc_y, rangeX1, rangeY1, rangeX2, rangeY2); if( m.is_touch( rangeX1, rangeY1, rangeX2, rangeY2, newNextXLoc, newNextYLoc, newNextXLoc+loc_width-1, newNextYLoc+loc_height-1 ) ) { stop_move(); } else //------- otherwise wait ---------// { set_wait(); } callingCount--; return 0; } } //--------- set the sprite_recno in new locations -----------// for(h=0, y=curNextYLoc; h<loc_height; h++, y++) { for(w=0, x=curNextXLoc; w<loc_width; w++, x++) world.get_loc(x,y)->remove_unit(mobile_type); } for(h=0, y=newNextYLoc; h<loc_height; h++, y++) { for(w=0, x=newNextXLoc; w<loc_width; w++, x++) world.get_loc(x,y)->set_unit(sprite_recno,mobile_type); } //----- set the new next coordinate ------// next_x = newNextX; next_y = newNextY; callingCount--; if( steps_remaining > 0 ) // steps_remaining can be decreased to negative as set_next() is called when stopping a unit, which is an addition to the steps it is supposed to move steps_remaining--; // --------- explore map ---------// if( cast_to_Unit() ) cast_to_Unit()->explore_on_move(curNextXLoc, curNextYLoc, newNextXLoc, newNextYLoc ); return 1; }