//--------- Begin of function sort_soldier_id_function ---------// // static int sort_soldier_id_function( const void *va, const void *vb ) { Soldier *a = &cur_firm_ptr->soldier_array[*((short*)va) - 1]; Soldier *b = &cur_firm_ptr->soldier_array[*((short*)vb) - 1]; int rc = a->is_under_training() - b->is_under_training(); if( rc == 0 ) return int( b->skill_level() - a->skill_level() ); else return rc; }
//--------- Begin of function sort_soldier_function ---------// // static int sort_soldier_function( const void *va, const void *vb ) { Soldier *a = (Soldier *)va; Soldier *b = (Soldier *)vb; int rc = a->is_under_training() - b->is_under_training(); if( rc == 0 ) return int( b->skill_level() - a->skill_level() ); else return rc; }
//---------- Begin of function FirmCamp::pay_expense --------// // // pay_expense() is called by Firm::next_day() // void FirmCamp::pay_expense() { if( !nation_recno ) return; Firm::pay_expense(); //-------- pay expenses to human units and weapons --------// Soldier* soldierPtr = soldier_array; Nation* nationPtr = nation_array[nation_recno]; for( int i=1 ; i<=soldier_count ; i++, soldierPtr++ ) { if( soldierPtr->is_under_training() ) continue; // #### begin Gilbert 24/3 #####// // int unitClass = unit_res[soldierPtr->unit_id]->unit_class; //------ if the unit is a weapon -------// // if( unitClass == UNIT_CLASS_WEAPON ) // one has life reduce hp when no food // one has no life, reduce hp when no money if( !unit_res[soldierPtr->unit_id]->class_info.life ) // #### end Gilbert 24/3 #####// { if( nationPtr->cash > 0 ) { nationPtr->add_expense( EXPENSE_WEAPON, (float) unit_res[soldierPtr->unit_id]->year_cost / 365, 1 ); } else { //-- if it's a weapon, decrease hit points if the nation cannot pay the unit --// if( soldierPtr->hit_points > 0 ) soldierPtr->hit_points--; if( soldierPtr->hit_points == 0 ) kill_soldier(i); // if its hit points is zero, delete it err_when( soldierPtr->hit_points < 0 ); } } } }
//------- Begin of function FirmCamp::basic_train -------// // // Training a villager into a soldier. // void FirmCamp::basic_train() { if( game.game_mode == GAME_TUTORIAL && nation_recno != nation_array.player_recno) return; for( int i = 1; i <= soldier_count; ++i ) { Soldier *soldierPtr = soldier_array + i - 1; // ###### begin Gilbert 19/11 #######// if( soldierPtr->is_under_training() ) { int basicCombatLevel = BASIC_COMBAT_TRAIN; // ###### patch begin Gilbert 16/2 ######// // if( nation_recno && soldierPtr->race_id == RACE_ROMAN // && god_res[GOD_ROMAN]->nation_prayer_count(nation_recno) > 0 ) if( nation_recno && god_res[GOD_ROMAN]->nation_prayer_count(nation_recno) > 0 ) { basicCombatLevel += BASIC_COMBAT_TRAIN / 2; // roman can train to combat level 30 } // ###### patch end Gilbert 16/2 ######// int totalBuildDays = unit_res[soldierPtr->unit_id]->build_days; soldierPtr->skill.inc_combat_level( ((float) basicCombatLevel + 0.125f)/ totalBuildDays ); soldierPtr->skill.inc_skill_level( ((float) BASIC_SKILL_TRAIN + 0.125f) / totalBuildDays ); // add a little more to avoid truncation error soldierPtr->hit_points = soldierPtr->max_hit_points(); if( soldierPtr->hit_points > soldierPtr->max_hit_points() ) soldierPtr->hit_points = soldierPtr->max_hit_points(); --soldierPtr->remain_build_days; err_when( soldierPtr->remain_build_days < 0 ); // ###### end Gilbert 19/11 #######// break; // only train one unit at a time. } } }
//------- Begin of function FirmCamp::advanced_train -------// // // Increase the leadership and ocmbat level of the general and the soldiers. // void FirmCamp::advanced_train() { if( game.game_mode == GAME_TUTORIAL && nation_recno != nation_array.player_recno) return; if( !overseer_recno ) return; Unit* overseerUnit = unit_array[overseer_recno]; int overseerSkill = (int) overseerUnit->skill_level(); // + overseerUnit->item.ability( ITEM_ABILITY_SKILL_LEVEL ); // skill_level() already contain enhancement int incValue; //------- increase the commander's leadership ---------// if( soldier_count > 0 && (int) overseerUnit->skill_level() < MAX_SKILL_TRAIN ) // do not use overseerSkill { //-- the more soldiers this commander has, the higher the leadership will increase ---// incValue = 5 * soldier_count * (int) overseerUnit->hit_points / overseerUnit->max_hit_points() * (100+overseerUnit->skill.skill_potential*2) / 100; // AI_CHEAT if( is_ai && config.ai_aggressiveness > OPTION_MODERATE ) incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 3; // 33% faster if aggressivness is high, 66% faster if aggressiveness is very high overseerUnit->skill.inc_skill_level( (float)incValue/100 ); } //------- increase the commander's combat level ---------// if( overseerUnit->combat_level() < MAX_COMBAT_TRAIN ) { incValue = 10 * (int) overseerUnit->hit_points / overseerUnit->max_hit_points() * (100+overseerUnit->skill.skill_potential*2) / 100; // ------ effect of god ----------// // ##### patch begin Gilbert 16/2 ######// // if( overseerUnit->race_id == RACE_CELTIC && nation_recno // && god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 ) if( nation_recno && god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 ) { if( overseerUnit->race_id == RACE_CELTIC ) incValue += incValue / 2; // 50% skill increase in fort else incValue += incValue / 5; // 20% skill increase in fort } // ##### patch end Gilbert 16/2 ######// if( is_ai && config.ai_aggressiveness > OPTION_MODERATE ) incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5; // 20% faster if aggressivness is high, 40% faster if aggressiveness is very high overseerUnit->skill.inc_combat_level( (float)incValue/100 ); } //------- increase the solider's combat level -------// for( int i=0 ; i<soldier_count ; i++ ) { Soldier* soldierPtr = soldier_array + i; #ifdef DEBUG err_when( !soldierPtr->name_id ); err_when( soldierPtr->is_monster() && monster_res.name_used_array[soldierPtr->name_id-1] < 1 ); #endif if( soldierPtr->is_under_training() ) // skip unit under initial training continue; //------- increase soldier skill -----------// if( soldierPtr->combat_level() < overseerSkill && soldierPtr->combat_level() < MAX_COMBAT_TRAIN ) { incValue = max(20, overseerSkill - (int)soldierPtr->combat_level()) * soldierPtr->hit_points / soldierPtr->max_hit_points() * (100+soldierPtr->skill.skill_potential*2+overseerUnit->item.ability(ITEM_ABILITY_TRAIN)) / 100; // ------ effect of god ----------// // ###### patch begin Gilbert 16/2 ######// //if( soldierPtr->race_id == RACE_CELTIC && nation_recno // && god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 ) if( nation_recno && god_res[GOD_CELTIC]->nation_prayer_count(nation_recno) > 0 ) { if( soldierPtr->race_id == RACE_CELTIC ) incValue += incValue / 2; // 50% skill increase in fort else incValue += incValue / 5; // 20% skill increase in fort } // ###### patch end Gilbert 16/2 ######// // ###### patch begin Gilbert 23/12 #########// // penalty of egyptain if( soldierPtr->race_id == RACE_EGYPTIAN && nation_recno && god_res[GOD_EGYPTIAN]->nation_prayer_count(nation_recno) > 0 ) { incValue = incValue * (MAX_WORKER*2) / (MAX_WORKER*2+god_res[GOD_EGYPTIAN]->nation_prayer_count(nation_recno)); } // ###### patch end Gilbert 23/12 #########// if( is_ai && config.ai_aggressiveness > OPTION_MODERATE ) incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5; // 20% faster if aggressivness is high, 40% faster if aggressiveness is very high soldierPtr->skill.inc_combat_level( (float)incValue/100 ); } //-- if the soldier has leadership potential, he learns leadership --// if( soldierPtr->skill.skill_potential > 0 && soldierPtr->skill_level() < MAX_SKILL_TRAIN ) { incValue = (int) max(50, overseerSkill-soldierPtr->skill_level()) * soldierPtr->hit_points / soldierPtr->max_hit_points() * soldierPtr->skill.skill_potential*2 / 100; if( is_ai && config.ai_aggressiveness > OPTION_MODERATE ) incValue += incValue * (config.ai_aggressiveness-OPTION_MODERATE) / 5; // 20% faster if aggressivness is high, 40% faster if aggressiveness is very high soldierPtr->skill.inc_skill_level( (float)incValue/100 ); } } }
int Unit::think_assign_soldier_to_camp() { //---- think about assign the unit to a camp/fort that needs soldiers ----// Nation* ownNation = nation_array[nation_recno]; FirmCamp *firmCamp, *bestFirm=NULL; int regionId = world.get_region_id( next_x_loc(), next_y_loc() ); int skillLevel = skill_level(); int curRating, bestRating=0; int curXLoc = next_x_loc(), curYLoc = next_y_loc(); for( int i=0 ; i<ownNation->ai_camp_count ; i++ ) { firmCamp = firm_array[ownNation->ai_camp_array[i]]->cast_to_FirmCamp(); if( firmCamp->nation_recno != nation_recno ) continue; if( firmCamp->region_id != regionId || firmCamp->under_construction ) continue; if( !firmCamp->can_accept_assign(sprite_recno) ) continue; curRating = 0; //----- if the camp is already full of soldier ------// if( firmCamp->is_soldier_full() ) { //---- get the lowest skill soldier of the firm -----// Soldier* soldierPtr = firmCamp->soldier_array; int minSkill=100; for( int j=0 ; j<firmCamp->soldier_count ; j++, soldierPtr++ ) { if( soldierPtr->is_under_training() ) continue; if( soldierPtr->skill_level() < minSkill ) minSkill = soldierPtr->skill_level(); } //------------------------------// if( firmCamp->majority_race() == race_id ) { if( skill_level() < minSkill+10 ) continue; } else //-- for different race, only assign if the skill is significantly higher than the existing ones --// { if( skill_level() < minSkill+30 ) continue; } } else { curRating += 300; // if the firm is not full, rating + 300 } //-------- calculate the rating ---------// curRating += world.distance_rating( curXLoc, curYLoc, firmCamp->center_x, firmCamp->center_y ); if( firmCamp->majority_race() == race_id ) curRating += 70; curRating += (MAX_SOLDIER - firmCamp->soldier_count) * 10; //-------------------------------------// if( curRating > bestRating ) { bestRating = curRating; bestFirm = firmCamp; } } if( bestFirm ) { assign(bestFirm->loc_x1, bestFirm->loc_y1); return 1; } else return 0; }
//--------- Begin of function FirmCamp::disp_camp_info ---------// // void FirmCamp::disp_camp_info(int dispY1, int refreshFlag) { if( is_own() ) { int x1 = INFO_X1 +13; int y1 = INFO_Y1 +235; int x2 = INFO_X1 +13; int y2 = INFO_Y1 +281; if( refreshFlag==INFO_REPAINT ) { // ##### begin Gilbert 31/12 #######// // button_patrol.create( INFO_X1+13, INFO_Y1+235, 'A', "PATROL" ); // button_reward.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+235, 'A', "REWARDCB" ); // button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+235, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" ); if (!is_monster()) button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "PATROL" ); else button_patrol.create( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, 'A', "F_PATROL" ); if (!is_monster()) button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "REWARD" ); else button_reward.create( INFO_X1+13, INFO_Y1+235, 'A', "F_REWARD" ); if (!is_monster()) button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "DEFENSE1" : "DEFENSE0" ); else button_defense.create( INFO_X1+13+2*BUTTON_DISTANCE, INFO_Y1+281, 'A', defense_flag ? "F_DEFEN1" : "F_DEFEN0" ); if (!is_monster()) button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "PROMOTE" ); else button_promote.create( INFO_X1+13+2*BUTTON_DISTANCE , INFO_Y1+235, 'A', "F_PROMOT" ); // ##### end Gilbert 31/12 #######// } if( overseer_recno ) { button_patrol.enable_flag = 1; } else { for( int i = 0; i < soldier_count && soldier_array[i].is_under_training(); ++i ); button_patrol.enable_flag = i < soldier_count; } String str; switch(patrol_state) { case PATROL_ALL: // str = "Sortie All"; str = ""; break; case PATROL_NO_GENERAL: str = "Sortie No Leader"; break; case PATROL_NO_INJURED_SOILDER: str = "Sortie No Injured"; break; default: break; } button_patrol.paint(); // vga.active_buf->bar_alpha( button_patrol.x1, button_patrol.y1+15, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-16, 1, 0 ); font_whbl.center_put_paragraph( button_patrol.x1, button_patrol.y1, button_patrol.x1+BUTTON_ACTION_WIDTH-1, button_patrol.y1+BUTTON_ACTION_HEIGHT-1, str ); // ###### begin Gilbert 15/4 ########// if( nation_array[nation_recno]->cash >= REWARD_COST && ( (overseer_recno && unit_array[overseer_recno]->rank_id != RANK_KING && unit_res[unit_array[overseer_recno]->unit_id]->class_info.has_loyalty) || (selected_soldier_id && selected_soldier_id <= soldier_count && unit_res[soldier_array[selected_soldier_id-1].unit_id]->class_info.has_loyalty)) ) button_reward.enable_flag = 1; // call paint // ###### end Gilbert 15/4 ########// else button_reward.enable_flag = 0; // call paint button_reward.paint(); if (!is_monster()) button_defense.update_bitmap( defense_flag ? "DEFENSE1" : "DEFENSE0" ); // call paint else button_defense.update_bitmap( defense_flag ? "F_DEFEN1" : "F_DEFEN0" ); if( (button_promote.visible_flag = !overseer_recno) ) { button_promote.enable_flag = 0; if( selected_soldier_id > 0 && selected_soldier_id <= soldier_count ) { Soldier *soldierPtr = soldier_array + selected_soldier_id - 1; // ##### begin Gilbert 24/3 ######// err_when( soldierPtr->unit_id == UNIT_WAGON ); if( soldierPtr->race_id != 0 && soldierPtr->rank_id == RANK_SOLDIER && !soldierPtr->is_under_training() && soldierPtr->skill_level() > 0 ) // ##### end Gilbert 24/3 ######// { button_promote.enable_flag = 1; } } button_promote.paint(); } } disp_spy_button( INFO_X1+13+BUTTON_DISTANCE, INFO_Y1+281, refreshFlag); }
//--------- Begin of function Nation::recruit_in_firm_soldier --------// // // Get soldiers currently in camps or forts for assigning them to another // camp or fort. // // <Firm*> destFirmPtr - the firm which the workers are recruited for. // // [int] preferedRaceId - the prefered race id. // (if not given, the majority race of the destination // firm will be used.) // // return: <int> recno of the unit recruited. // int Nation::recruit_in_firm_soldier(Firm* destFirmPtr, int preferedRaceId) { err_when( destFirmPtr->cast_to_FirmCamp() == NULL ); // it must either be a Camp or a Fort if( !preferedRaceId ) { preferedRaceId = destFirmPtr->majority_race(); if( !preferedRaceId ) return 0; } //--- scan existing firms to see if any of them have excess workers ---// FirmCamp* firmCamp, *bestFirmCamp=NULL; int bestRating=0, curRating; int bestFirmSoldierId=0; int i; for( i=0 ; i<ai_camp_count ; i++ ) { firmCamp = firm_array[ai_camp_array[i]]->cast_to_FirmCamp(); err_when( !firmCamp ); if( firmCamp->firm_recno == destFirmPtr->firm_recno ) continue; if( firmCamp->region_id != destFirmPtr->region_id ) continue; int excessCombatLevel = firmCamp->total_combat_level() - firmCamp->ai_combat_level_needed(); curRating = excessCombatLevel/3 + world.distance_rating( firmCamp->center_x, firmCamp->center_y, destFirmPtr->center_x, destFirmPtr->center_y ); for( int j=0 ; j<firmCamp->soldier_count ; j++ ) { if( firmCamp->soldier_array[j].is_under_training() ) continue; if( firmCamp->soldier_array[j].race_id == preferedRaceId ) curRating += 50; } if( curRating > bestRating ) { bestRating = curRating; bestFirmCamp = firmCamp; } } if( !bestFirmCamp ) return 0; //------ mobilize a worker form the selected firm ----// int bestSoldierId=0; bestRating = 0; Soldier* soldierPtr = bestFirmCamp->soldier_array; for( i=0 ; i<bestFirmCamp->soldier_count ; i++, soldierPtr++ ) { if( soldierPtr->is_under_training() ) continue; if( soldierPtr->race_id == preferedRaceId ) // same race curRating = 50; else if( soldierPtr->race_id == 0 ) // weapon curRating = 20; else // different race curRating = 10; if( curRating > bestRating ) { bestRating = curRating; bestSoldierId = i+1; } } if( !bestSoldierId ) return NULL; return bestFirmCamp->mobilize_soldier( bestSoldierId, COMMAND_AI ); }