void UnitGroup::exe_assign(int destXLoc, int destYLoc, int targetMobileType, int actionNationRecno) { //---------------------------------------// Unit* unitPtr; int locX, locY; int right = 0; int left = 0; int midX = 0; int top = 0; int bottom = 0; int midY = 0; if(size() == 1) { unitPtr = get_unit(1); unitPtr->set_no_longer_in_formation(); unitPtr->assign(destXLoc, destYLoc, actionNationRecno); return; } Location* locPtr; locPtr = world.get_loc(destXLoc, destYLoc); int baseObjRecno = locPtr->base_obj_recno(targetMobileType); // ###### begin Gilbert 6/5 #######// if( !baseObjRecno ) return; // ###### end Gilbert 6/5 #######// BaseObj* thePlace = base_obj_array[baseObjRecno]; int destWidth = thePlace->obj_loc_width(); int destHeight = thePlace->obj_loc_height(); for(int i = 1; i<=size(); i++) { unitPtr = get_unit(i); unitPtr->set_no_longer_in_formation(); locX = unitPtr->next_x_loc(); locY = unitPtr->next_y_loc(); if(locX < destXLoc) //left left++; else if(locX > destXLoc+destWidth-1) //right right++; else midX++; if(locY < destYLoc) //top top++; else if(locY > destYLoc+destHeight-1) //bottom bottom++; else midY++; } if(!left && !midX) //all at right side { run_action( destXLoc, destYLoc, UNIT_ASSIGN, baseObjRecno ); return; } if(!right && !midX) //all at left side { run_action( destXLoc, destYLoc, UNIT_ASSIGN, baseObjRecno ); return; } if(!top && !midY) //all at bottom side { run_action( destXLoc, destYLoc, UNIT_ASSIGN, baseObjRecno); return; } if(!bottom && !midY) //all at top side { run_action(destXLoc, destYLoc, UNIT_ASSIGN, baseObjRecno); return; } for(i=1; i<=size(); i++) { unitPtr = get_unit(i); unitPtr->assign(destXLoc, destYLoc, actionNationRecno); } }
void UnitGroup::exe_attack(int targetObjRecno) { BaseObj *targetObj = base_obj_array[targetObjRecno]; int targetWidth = targetObj->obj_loc_width(); int targetHeight = targetObj->obj_loc_height(); int targetLocX = targetObj->obj_loc_x1(); int targetLocY = targetObj->obj_loc_y1(); /* int testLocX, testLocY; int index, unitIndex; int maxWidth=0, maxHeight=0; Unit* unitPtr; int w, h; int rangeAttack=0, closeAttack=0; int minAttackRange = 0; int distance; Unit** arrayForRangeAttack=NULL, **arrayForCloseAttack=NULL; int numberAttacking = 0; */ //--looking for the maximum range, size of the units ---// //--and counting how many units will do range attack and close attack respectively---// /* for(int i=1; i<=size(); i++) { unitPtr = get_unit(i); if(!unitPtr->can_attack()) continue; //---------------------------------------------// if(unitPtr->cur_action == SPRITE_ATTACK && unitPtr->cur_order.para == targetObjRecno) { numberAttacking++; continue; } // ##### begin Gilbert 4/11 ######// // distance = unitPtr->cal_distance(targetLocX, targetLocY, targetWidth, targetHeight); distance = unitPtr->area_distance(targetObj); // ##### end Gilbert 4/11 ######// unitPtr->choose_best_attack_mode(distance, targetObj->obj_mobile_type()); if(unitPtr->obj_loc_width() > maxWidth) maxWidth = unitPtr->obj_loc_width(); if(unitPtr->obj_loc_height() > maxHeight) maxHeight = unitPtr->obj_loc_height(); if((unitPtr->attack_range() < minAttackRange) && (unitPtr->attack_range()>1)) minAttackRange = unitPtr->attack_range(); if(unitPtr->attack_range() > 1) rangeAttack++; else closeAttack++; } //---------------------------------------------------------// // err_when(!rangeAttack && !closeAttack); if(!rangeAttack && !closeAttack) return; if(rangeAttack) arrayForRangeAttack = (Unit**) mem_add(sizeof(Unit*)*rangeAttack); if(closeAttack) arrayForCloseAttack = (Unit**) mem_add(sizeof(Unit*)*closeAttack); int iRa = 0, iCa = 0; //---- separate the units into two arrays by means of their attacking mode ---// for(i=1; i<=size(); i++) { unitPtr = get_unit(i); if(!unitPtr->can_attack()) continue; if(unitPtr->cur_action == SPRITE_ATTACK && unitPtr->cur_order.para == targetObjRecno) continue; if(unitPtr->attack_range()>1) arrayForRangeAttack[iRa++] = unitPtr; else arrayForCloseAttack[iCa++] = unitPtr; } err_when(!maxWidth); err_when(!maxHeight); //----- assign a good location for the units to undergo range attack -----// if(rangeAttack) { int xLoc1 = max(targetLocX-minAttackRange, 0); int yLoc1 = max(targetLocY-minAttackRange, 0); int xLoc2 = min(targetLocX+targetWidth-1+minAttackRange, MAX_WORLD_X_LOC-1); int yLoc2 = min(targetLocY+targetHeight-1+minAttackRange, MAX_WORLD_Y_LOC-1); int checkXLoc, checkYLoc; unitIndex = 0; unitPtr = arrayForRangeAttack[unitIndex]; //-------- checking for surrounding location ----------// for(checkXLoc=xLoc1; checkXLoc<=xLoc2; checkXLoc++) { if(unitPtr->can_move(checkXLoc, yLoc1)) { unitPtr->attack_loc_offset_x = checkXLoc-targetLocX; unitPtr->attack_loc_offset_y = yLoc1-targetLocY; if(unitPtr->obj_loc_width()>1) checkXLoc += (unitPtr->obj_loc_width()-1); if(unitIndex<rangeAttack-1) unitPtr = arrayForRangeAttack[++unitIndex]; else break; } } if(unitIndex < rangeAttack) { for(checkYLoc=yLoc1+1; checkYLoc<yLoc2; checkYLoc++) { if(unitPtr->can_move(xLoc1, checkYLoc)) { unitPtr->attack_loc_offset_x = xLoc1-targetLocX; unitPtr->attack_loc_offset_y = checkYLoc-targetLocY; if(unitPtr->obj_loc_height() > 1) checkYLoc += (unitPtr->obj_loc_height()-1); if(unitIndex < rangeAttack-1) unitPtr = arrayForRangeAttack[++unitIndex]; else break; } } } if(unitIndex < rangeAttack) { for(checkXLoc=xLoc1; checkXLoc<=xLoc2; checkXLoc++) { if(unitPtr->can_move(checkXLoc, yLoc2)) { unitPtr->attack_loc_offset_x = checkXLoc-targetLocX; unitPtr->attack_loc_offset_y = yLoc2-targetLocY; if(unitPtr->obj_loc_width() > 1) checkXLoc+= (unitPtr->obj_loc_width()-1); if(unitIndex < rangeAttack-1) unitPtr= arrayForRangeAttack[++unitIndex]; else break; } } } if(unitIndex < rangeAttack) { for(checkYLoc=yLoc1+1; checkYLoc<yLoc2; checkYLoc++) { if(unitPtr->can_move(xLoc2, checkYLoc)) { unitPtr->attack_loc_offset_x = xLoc2-targetLocX; unitPtr->attack_loc_offset_y = checkYLoc-targetLocY; if(unitPtr->obj_loc_height() > 1) checkYLoc+=(unitPtr->obj_loc_height()-1); if(unitIndex < rangeAttack-1) unitPtr = arrayForRangeAttack[++unitIndex]; else break; } } } if(unitIndex < rangeAttack) { for(; unitIndex<rangeAttack; unitIndex++) { unitPtr = arrayForRangeAttack[unitIndex]; //--settting attack_loc_offset_? to 0 will make them cannot attack --// unitPtr->attack_loc_offset_x = 0; unitPtr->attack_loc_offset_y = 0; } } } //---- finding a good location for the units undergoing close attack -----// if(closeAttack) { unitIndex = 0; unitPtr = arrayForCloseAttack[unitIndex]; if((testLocY=targetLocY-maxHeight) >= 0) //has top edge { w = unitPtr->obj_loc_width(); while(w>=0) { if(targetLocX >= w) { index = -w; break; } w--; } err_when(index>0); for(; index<targetWidth; index++) { if(unitPtr->can_move(targetLocX+index, testLocY)) { unitPtr->attack_loc_offset_x = index; unitPtr->attack_loc_offset_y = -maxHeight; if(unitPtr->obj_loc_width() > 1) index += (unitPtr->obj_loc_width()-1); if(unitIndex < closeAttack-1) unitPtr = arrayForCloseAttack[++unitIndex]; //get_next_unit else break; } } } if((unitIndex < closeAttack) && ((testLocX = targetLocX + targetWidth) <= MAX_WORLD_X_LOC-maxWidth)) //has right edge { h = unitPtr->obj_loc_height(); while(h>=0) { if(targetLocY >= h) { index = -h; break; } h--; } err_when(index>0); for(; index<targetHeight; index++) { if(unitPtr->can_move(testLocX, targetLocY+index)) { unitPtr->attack_loc_offset_x = targetWidth; unitPtr->attack_loc_offset_y = index; if(unitPtr->obj_loc_height() > 1) index += (unitPtr->obj_loc_height()-1); if(unitIndex < closeAttack-1) unitPtr = arrayForCloseAttack[++unitIndex]; //get next unit else break; } } } if((unitIndex < closeAttack) && ((testLocY = targetLocY + targetHeight) <= MAX_WORLD_Y_LOC-maxHeight)) //has bottom edge { w = unitPtr->obj_loc_width(); while(w>=0) { if(targetLocX+targetWidth<=MAX_WORLD_X_LOC-w) { index = targetWidth-(unitPtr->obj_loc_width()-w); break; } w--; } for(; index>=0; index--) { if(unitPtr->can_move(targetLocX+index, testLocY)) { unitPtr->attack_loc_offset_x = index; unitPtr->attack_loc_offset_y = targetHeight; if(unitIndex < closeAttack-1) { unitPtr = arrayForCloseAttack[++unitIndex]; if(unitPtr->obj_loc_width() > 1) index -= (unitPtr->obj_loc_width()-1); } else break; } } } if(unitIndex < closeAttack && ((testLocX = targetLocX-maxWidth) >=0 )) //has left edge { h = unitPtr->obj_loc_height(); while(h>=0) { if(targetLocY+targetHeight<=MAX_WORLD_Y_LOC-h) { index = targetHeight-(unitPtr->obj_loc_height()-h); break; } h--; } for(; index>=0; index--) { if(unitPtr->can_move(testLocX, targetLocY+index)) { unitPtr->attack_loc_offset_x = -1; unitPtr->attack_loc_offset_y = index; if(unitIndex < closeAttack-1) { unitPtr = arrayForCloseAttack[++unitIndex]; if(unitPtr->obj_loc_height() > 1) index -= (unitPtr->obj_loc_height()-1); } else break; } } } //----for those who cannot find a good position, cannot attack //---- setting the attack_loc_offset_? to 0 means they cannot attack -----// if(unitIndex < closeAttack) { while(unitIndex < closeAttack-1) { unitPtr->attack_loc_offset_x = 0; unitPtr->attack_loc_offset_y = 0; unitPtr = arrayForCloseAttack[++unitIndex]; } unitPtr->attack_loc_offset_x = 0; unitPtr->attack_loc_offset_y = 0; } } */ cluster_units_for_attack(targetObjRecno, targetLocX, targetLocY, targetWidth, targetHeight); /* if(arrayForRangeAttack) mem_del(arrayForRangeAttack); if(arrayForCloseAttack) mem_del(arrayForCloseAttack); */ }