//--------- Begin of function Unit::handle_blocked_attack_wall ---------// // handle the case that the way of this unit to the target wall is blocked by // another unit // // <Unit*> unitPtr - the blocking unit // void Unit::handle_blocked_attack_wall(Unit *unitPtr) { if(action_x_loc==unitPtr->action_x_loc && action_y_loc==unitPtr->action_y_loc && action_mode==unitPtr->action_mode) { //------------- both attacks the same wall ------------// Location *locPtr = world.get_loc(action_x_loc, action_y_loc); if(!locPtr->is_wall()) stop2(KEEP_DEFENSE_MODE); // stop since wall is deleted else if(space_for_attack(action_x_loc, action_y_loc, UNIT_LAND, 1, 1)) { //------------ found surrounding place to attack the wall -------------// if(mobile_type==UNIT_LAND) set_move_to_surround(action_x_loc, action_y_loc, 1, 1, BUILDING_TYPE_WALL); // search for a unit only, not for a group else attack_wall(action_x_loc, action_y_loc); } else // no surrounding place found, stop now stop(KEEP_PRESERVE_ACTION); // no space available, so stop to wait for space to attack the wall } else { if(action_x_loc==-1 || action_y_loc==-1) stop(); else set_wait(); } }
//------ Begin of function Unit::handle_blocked_same_target_attack ---------// // the target of the blocked unit and this unit are same // // <Unit*> unitPtr - pointer to blocking uit // <Unit*> targetPtr - pointer to target unit // void Unit::handle_blocked_same_target_attack(Unit* unitPtr, Unit* targetPtr) { //----------------------------------------------------------// // this unit is now waiting and the unit pointed by unitPtr // is attacking the unit pointed by targetPtr //----------------------------------------------------------// err_when(cur_x%ZOOM_LOC_WIDTH || cur_y%ZOOM_LOC_HEIGHT); err_when(cur_x!=next_x || cur_y!=next_y); err_when(cur_x==go_x && cur_y==go_y); if(space_for_attack(action_x_loc, action_y_loc, targetPtr->mobile_type, targetPtr->sprite_info->loc_width, targetPtr->sprite_info->loc_height)) { err_when(action_x_loc!=action_x_loc2 || action_y_loc!=action_y_loc2); search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_TO_ATTACK, targetPtr->sprite_recno); //search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_TO_ATTACK, targetPtr->sprite_recno); } else if(in_any_defense_mode()) { err_when(action_mode2!=ACTION_AUTO_DEFENSE_ATTACK_TARGET && action_mode2!=ACTION_DEFEND_TOWN_ATTACK_TARGET && action_mode2!=ACTION_MONSTER_DEFEND_ATTACK_TARGET); general_defend_mode_detect_target(); } else if(m.points_distance(next_x_loc(), next_y_loc(), action_x_loc, action_y_loc)<ATTACK_DETECT_DISTANCE) { //------------------------------------------------------------------------// // if the target is within the detect range, stop the unit's action to detect // another target if any exist. In case, there is no other target, the unit // will still attack the original target since it is the only target in the // detect range //------------------------------------------------------------------------// stop2(KEEP_DEFENSE_MODE); } else set_wait(); // set wait to stop the movement }
/* ** Perform a reduce action and the shift that must immediately ** follow the reduce. */ static void yy_reduce( yyParser *yypParser, /* The parser */ int yyruleno /* Number of the rule by which to reduce */ ){ int yygoto; /* The next state */ int yyact; /* The next action */ YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ ParseARG_FETCH; yymsp = &yypParser->yystack[yypParser->yyidx]; #ifndef NDEBUG if( yyTraceFILE && yyruleno>=0 && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, yyRuleName[yyruleno]); } #endif /* NDEBUG */ /* Silence complaints from purify about yygotominor being uninitialized ** in some cases when it is copied into the stack after the following ** switch. yygotominor is uninitialized when a rule reduces that does ** not set the value of its left-hand side nonterminal. Leaving the ** value of the nonterminal uninitialized is utterly harmless as long ** as the value is never used. So really the only thing this code ** accomplishes is to quieten purify. ** ** 2007-01-16: The wireshark project (www.wireshark.org) reports that ** without this code, their parser segfaults. I'm not sure what there ** parser is doing to make this happen. This is the second bug report ** from wireshark this week. Clearly they are stressing Lemon in ways ** that it has not been previously stressed... (SQLite ticket #2172) */ /*memset(&yygotominor, 0, sizeof(yygotominor));*/ yygotominor = yyzerominor; switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example ** follows: ** case 0: ** #line <lineno> <grammarfile> ** { ... } // User supplied code ** #line <lineno> <thisfile> ** break; */ case 4: /* decl ::= REPORT TO STR */ #line 22 "cfg.y" {set_report(ps,yymsp[0].minor.yy0);} #line 739 "cfg.c" break; case 5: /* decl ::= LISTEN ON STR */ #line 23 "cfg.y" {set_listen(ps,yymsp[0].minor.yy0);} #line 744 "cfg.c" break; case 6: /* job ::= JOB LCURLY sbody RCURLY */ #line 24 "cfg.y" {push_job(ps);} #line 749 "cfg.c" break; case 9: /* kv ::= NAME STR */ #line 27 "cfg.y" {set_name(ps,yymsp[0].minor.yy0);} #line 754 "cfg.c" break; case 11: /* kv ::= DIR path */ #line 29 "cfg.y" {set_dir(ps,yymsp[0].minor.yy0);} #line 759 "cfg.c" break; case 12: /* kv ::= OUT path */ #line 30 "cfg.y" {set_out(ps,yymsp[0].minor.yy0);} #line 764 "cfg.c" break; case 13: /* kv ::= IN path */ #line 31 "cfg.y" {set_in(ps,yymsp[0].minor.yy0);} #line 769 "cfg.c" break; case 14: /* kv ::= ERR path */ #line 32 "cfg.y" {set_err(ps,yymsp[0].minor.yy0);} #line 774 "cfg.c" break; case 15: /* kv ::= USER STR */ #line 33 "cfg.y" {set_user(ps,yymsp[0].minor.yy0);} #line 779 "cfg.c" break; case 16: /* kv ::= ORDER STR */ #line 34 "cfg.y" {set_ord(ps,yymsp[0].minor.yy0);} #line 784 "cfg.c" break; case 17: /* kv ::= ENV STR */ #line 35 "cfg.y" {set_env(ps,yymsp[0].minor.yy0);} #line 789 "cfg.c" break; case 18: /* kv ::= ULIMIT STR STR */ case 34: /* pairs ::= pairs STR STR */ yytestcase(yyruleno==34); #line 36 "cfg.y" {set_ulimit(ps,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} #line 795 "cfg.c" break; case 20: /* kv ::= DISABLED */ #line 38 "cfg.y" {set_dis(ps); } #line 800 "cfg.c" break; case 21: /* kv ::= WAIT */ #line 39 "cfg.y" {set_wait(ps); } #line 805 "cfg.c" break; case 22: /* kv ::= ONCE */ #line 40 "cfg.y" {set_once(ps); } #line 810 "cfg.c" break; case 23: /* kv ::= BOUNCE EVERY STR */ #line 41 "cfg.y" {set_bounce(ps,yymsp[0].minor.yy0);} #line 815 "cfg.c" break; case 25: /* cmd ::= path */ #line 43 "cfg.y" {set_cmd(ps,yymsp[0].minor.yy0);} #line 820 "cfg.c" break; case 26: /* cmd ::= path args */ #line 44 "cfg.y" {set_cmd(ps,yymsp[-1].minor.yy0);} #line 825 "cfg.c" break; case 27: /* path ::= STR */ case 30: /* arg ::= STR */ yytestcase(yyruleno==30); #line 45 "cfg.y" {yygotominor.yy0=yymsp[0].minor.yy0;} #line 831 "cfg.c" break; case 28: /* args ::= args arg */ case 29: /* args ::= arg */ yytestcase(yyruleno==29); #line 46 "cfg.y" {utarray_push_back(&ps->job->cmdv,&yymsp[0].minor.yy0);} #line 837 "cfg.c" break; case 31: /* arg ::= QUOTEDSTR */ #line 49 "cfg.y" {yygotominor.yy0=unquote(yymsp[0].minor.yy0);} #line 842 "cfg.c" break; case 32: /* paths ::= paths path */ case 33: /* paths ::= path */ yytestcase(yyruleno==33); #line 50 "cfg.y" {utarray_push_back(&ps->job->depv,&yymsp[0].minor.yy0);} #line 848 "cfg.c" break; default: /* (0) file ::= decls */ yytestcase(yyruleno==0); /* (1) decls ::= decls job */ yytestcase(yyruleno==1); /* (2) decls ::= decls decl */ yytestcase(yyruleno==2); /* (3) decls ::= */ yytestcase(yyruleno==3); /* (7) sbody ::= sbody kv */ yytestcase(yyruleno==7); /* (8) sbody ::= kv */ yytestcase(yyruleno==8); /* (10) kv ::= CMD cmd */ yytestcase(yyruleno==10); /* (19) kv ::= ULIMIT LCURLY pairs RCURLY */ yytestcase(yyruleno==19); /* (24) kv ::= DEPENDS LCURLY paths RCURLY */ yytestcase(yyruleno==24); /* (35) pairs ::= */ yytestcase(yyruleno==35); break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); if( yyact < YYNSTATE ){ #ifdef NDEBUG /* If we are not debugging and the reduce action popped at least ** one element off the stack, then we can push the new element back ** onto the stack here, and skip the stack overflow test in yy_shift(). ** That gives a significant speed improvement. */ if( yysize ){ yypParser->yyidx++; yymsp -= yysize-1; yymsp->stateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yymsp->minor = yygotominor; }else #endif { yy_shift(yypParser,yyact,yygoto,&yygotominor); } }else{ assert( yyact == YYNSTATE + YYNRULE + 1 ); yy_accept(yypParser); } }
//------ Begin of function Unit::search_or_wait ---------// // call searching or wait // void Unit::search_or_wait() { #define SQUARE1 9 #define SQUARE2 25 #define SQUARE3 49 #define DIMENSION 7 int curXLoc = next_x_loc(), curYLoc = next_y_loc(); short surrArray[SQUARE3]; int xShift, yShift, checkXLoc, checkYLoc, hasFree, i, shouldWait; short unitRecno; Unit *unitPtr; Location *locPtr; //----------------------------------------------------------------------------// // wait if the unit is totally blocked. Otherwise, call searching //----------------------------------------------------------------------------// memset(surrArray, 0, sizeof(short)*SQUARE3); for(shouldWait=0, hasFree=0, i=2; i<=SQUARE3; i++) { if(i==SQUARE1 || i==SQUARE2 || i==SQUARE3) { if(!hasFree) { shouldWait++; break; } else hasFree = 0; } m.cal_move_around_a_point(i, DIMENSION, DIMENSION, xShift, yShift); checkXLoc = curXLoc+xShift; checkYLoc = curYLoc+yShift; if(checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC) continue; locPtr = world.get_loc(checkXLoc, checkYLoc); if(!locPtr->has_unit(mobile_type)) { hasFree++; continue; } unitRecno = locPtr->unit_recno(mobile_type); err_when(!unitRecno); if(unit_array.is_deleted(unitRecno)) continue; unitPtr = unit_array[unitRecno]; if(unitPtr->nation_recno==nation_recno && unitPtr->unit_group_id==unit_group_id && ((unitPtr->cur_action==SPRITE_WAIT && unitPtr->waiting_term>1) || unitPtr->cur_action==SPRITE_TURN || unitPtr->cur_action==SPRITE_MOVE)) { surrArray[i-2] = unitRecno; unitPtr->unit_group_id++; } } //------------------- call searching if should not wait --------------------// if(!shouldWait) search(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_IN_A_GROUP); //search_or_stop(move_to_x_loc, move_to_y_loc, 1, SEARCH_MODE_IN_A_GROUP); for(i=0; i<SQUARE3; i++) { if(surrArray[i]) { err_when(unit_array.is_deleted(surrArray[i])); unitPtr = unit_array[surrArray[i]]; unitPtr->unit_group_id--; } } if(shouldWait) set_wait(); }
//------ 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::move_to ---------// // // Move a unit to a specified location // // <int> destXLoc - the x-coordinate of the destination // <int> destYLoc - the y-coordinate of the destination // <bool> raiseDest - default is true, if not want to raise destination, false // void UnitB::move_to(int destXLoc, int destYLoc, bool raiseDest) { // ###### begin Gilbert 22/3 #######// // other people may ask this unit to move away while it is dead if( hit_points <= 0 || cur_action == SPRITE_DIE ) return; // ###### end Gilbert 22/3 #######// // err_when(destXLoc < 0 || destXLoc >= MAX_WORLD_X_LOC || destYLoc < 0 || destYLoc >= MAX_WORLD_Y_LOC); destXLoc = min(destXLoc, MAX_WORLD_X_LOC-1); destXLoc = max(destXLoc, 0); destYLoc = min(destYLoc, MAX_WORLD_Y_LOC-1); destYLoc = max(destYLoc, 0); stop_move(); //--- save the destination for later possible retries in searching when it is blocked ----// move_to_loc_x = destXLoc; move_to_loc_y = destYLoc; if((destXLoc == next_x_loc()) && (destYLoc == next_y_loc())) return; //------- search the path ---------// //#ifdef DEBUG // unsigned long pathFinderStartTime = m.get_time(); //#endif path_finder.set_attribute(loc_width, loc_height, mobile_type, 0); // ###### begin Gilbert 31/5 #######// err_when( cur_order.mode == UNIT_ATTACK && !cast_to_Unit() ); int stopAtRange = cur_order.mode == UNIT_ATTACK ? cast_to_Unit()->attack_range()-1 : 0; // subtract one attack_range so close attack can search near the target // and range attack search a little closer // ###### end Gilbert 31/5 #######// //----- code for handle nation power option -----// bool handlePowerNationFlag = false; path_finder.set_handle_power_nation(0); if( nation_recno ) { Nation *nationPtr = nation_array[nation_recno]; int srcLocPowerNation = world.get_loc(next_x_loc(), next_y_loc())->power_nation_recno; int destLocPowerNation = world.get_loc(destXLoc, destYLoc)->power_nation_recno; //--- only if unit stands on a passable location and the destination is passable, we handle power nation ---// if( (!srcLocPowerNation || nationPtr->get_relation_passable(srcLocPowerNation)) && (!destLocPowerNation || nationPtr->get_relation_passable(destLocPowerNation)) ) { path_finder.set_handle_power_nation(1, nationPtr->relation_passable_array ); handlePowerNationFlag = true; } } //--------- find the path now ---------// int rangeX1, rangeY1, rangeX2, rangeY2; get_object_range(destXLoc, destYLoc, rangeX1, rangeY1, rangeX2, rangeY2); // ######## begin Gilbert 31/5 ##########// path_finder.find_path(next_x_loc(), next_y_loc(), destXLoc, destYLoc, rangeX1, rangeY1, rangeX2, rangeY2, 1, raiseDest, 0, stopAtRange ); // ######## end Gilbert 31/5 ##########// if( path_finder.is_path_found() ) { set_no_longer_blocked(); seek_path_fail_count=0; // reset the failure counter } else //---- path searching failed ----// { if(!is_blocked()) set_not_seriously_blocked(); //--- if the path search failed, increase the failure counter ---// // if( seek_path_fail_count < 100 ) // prevent numeric overflow // seek_path_fail_count++; } //-----------------------------------------// int pathNodeCount; int totalSteps; // total number of steps to walk through the whole path. if( cur_path ) mem_del( cur_path ); cur_path = path_finder.retrieve(pathNodeCount, totalSteps); // retrieves the path // ###### begin Gilbert 11/5 #########// if( cur_path ) { cur_path_result_id = pathNodeCount; // start with the last node steps_remaining = totalSteps; } else { cur_path_result_id = 0; steps_remaining = 0; } // ###### end Gilbert 11/5 #########// //#ifdef DEBUG // // ######## begin Gilbert 27/4 #######// // pathFinderStartTime = m.get_time() - pathFinderStartTime; // pathfind_profile_time += pathFinderStartTime; // pathfind_count++; // if( pathFinderStartTime > longest_pathfind_profile_time ) // { // longest_pathfind_profile_time = pathFinderStartTime; // longest_pathfind_unit_recno = sprite_recno; // } // // ######## begin Gilbert 27/4 #######// //#endif if(!cur_path) { if(handlePowerNationFlag) { // ##### begin Gilber 27/4 ########// //#ifdef DEBUG // unsigned long pathFinderStartTime = m.get_time(); // pathFinderStartTime = m.get_time(); //#endif // ##### end Gilber 27/4 ########// // ###### begin Gilbert 12/5 ########// // path_finder.set_attribute(loc_width, loc_height, mobile_type, PFIND_IGNORE_UNIT ); // ###### end Gilbert 12/5 ########// path_finder.set_handle_power_nation(0); handlePowerNationFlag = false; // ######## begin Gilbert 31/5 ##########// path_finder.find_path(next_x_loc(), next_y_loc(), destXLoc, destYLoc, rangeX1, rangeY1, rangeX2, rangeY2, 1, raiseDest, 0, stopAtRange ); // ######## end Gilbert 31/5 ##########// if( path_finder.is_path_found() ) { set_no_longer_blocked(); seek_path_fail_count=0; // reset the failure counter } else //---- path searching failed ----// { if(!is_blocked()) set_not_seriously_blocked(); } if( cur_path ) mem_del( cur_path ); cur_path = path_finder.retrieve(pathNodeCount, totalSteps); // retrieves the path // ###### begin Gilbert 11/5 #########// if( cur_path ) { cur_path_result_id = pathNodeCount; // start with the last node steps_remaining = totalSteps; } else { cur_path_result_id = 0; steps_remaining = 0; } // ###### end Gilbert 11/5 #########// //#ifdef DEBUG // // ######## begin Gilbert 27/4 #######// // pathFinderStartTime = m.get_time() - pathFinderStartTime; // pathfind_profile_time += pathFinderStartTime; // pathfind_count++; // if( pathFinderStartTime > longest_pathfind_profile_time ) // { // longest_pathfind_profile_time = pathFinderStartTime; // longest_pathfind_unit_recno = sprite_recno; // } // // ######## begin Gilbert 27/4 #######// //#endif if(!cur_path) { if(!handle_blocking()) set_no_longer_blocked(); if(seek_path_fail_count <= 100*SEEK_PATH_FAIL_INCREMENT) seek_path_fail_count+=SEEK_PATH_FAIL_INCREMENT; // 10 is the single increment unit. It will be reduce by 1 each time in Unit::attack() } } else { if(!handle_blocking()) set_no_longer_blocked(); if(seek_path_fail_count <= 100*SEEK_PATH_FAIL_INCREMENT) seek_path_fail_count+=SEEK_PATH_FAIL_INCREMENT; } } //--------- start the first move ---------// if( cur_path && cur_action != SPRITE_MOVE ) // if it is previously moving, don't call next_move() as it has still yet to finish its remaining pixel move to snap to grids { cur_action = SPRITE_MOVE; cur_frame = 1; retry_state = 0; } else { // ###### begin Gilbert 15/5 #########// if( cur_x == next_x && cur_y == next_y ) { wait_count = 0; set_wait(); } // ###### end Gilbert 15/5 #########// } }
//--------- 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; }