void FirmInn::add_inn_unit(int unitId) { err_when( inn_unit_count >= MAX_INN_UNIT ); InnUnit *innUnit = inn_unit_array+inn_unit_count; inn_unit_count++; innUnit->unit_id = unitId; //--------- set the skill now -----------------// char skillId = (char) next_skill_id; if( ++next_skill_id > MAX_TRAINABLE_SKILL ) next_skill_id = 1; innUnit->skill.skill_id = skillId; if( skillId > 0 ) innUnit->skill.skill_level = 30+misc.random(70); else innUnit->skill.skill_level = 0; if( skillId==0 || skillId==SKILL_LEADING ) innUnit->skill.combat_level = 30+misc.random(70); else innUnit->skill.combat_level = 10; innUnit->set_hire_cost(); innUnit->stay_count = 5 + misc.random(5); innUnit->spy_recno = 0; }
// ------- Begin of function FirmInn::buy_item ------// // // checkingFlag : false = buy , 1 = check if can buy // int FirmInn::buy_item( short recNo, int checkingFlag ) { err_when( recNo < 1 ); if( recNo > inn_unit_count ) // this may happen in a multiplayer game return 0; //--------- first check if you have enough money to hire, unless own spy ------// Nation* nationPtr = nation_array[nation_recno]; InnUnit* innUnit = inn_unit_array+recNo-1; if( !innUnit->item.id ) return 0; if( innUnit->true_nation_recno() != nation_recno && nationPtr->cash < innUnit->item.cost() ) return 0; if( !checkingFlag ) { // drop the item outside if( site_array.add_site( loc_x2, loc_y2, SITE_ITEM, innUnit->item.id, innUnit->item.para ) || site_array.add_site( loc_x2, loc_y1, SITE_ITEM, innUnit->item.id, innUnit->item.para ) || site_array.add_site( loc_x1, loc_y2, SITE_ITEM, innUnit->item.id, innUnit->item.para ) || site_array.add_site( loc_x1, loc_y1, SITE_ITEM, innUnit->item.id, innUnit->item.para ) ) { // reduce nation cash if( innUnit->true_nation_recno() != nation_recno ) { nationPtr->add_expense( EXPENSE_HIRE_UNIT, (float) innUnit->item.cost(), 0 ); } // clear item innUnit->item.clear(); // recalc hire cost innUnit->set_hire_cost(); return 1; } return 0; } return 1; }
//--------- Begin of function FirmInn::assign_unit ---------// // void FirmInn::assign_unit(int unitRecno) { Unit* unitPtr = unit_array[unitRecno]; //--- can only assign if the unit is a spy cloaked into independent ---// if( !can_accept_assign(unitRecno) ) return; //---------------------------------------------// if( inn_unit_count == MAX_INN_UNIT || count_soldier() >= MAX_INN_UNIT/2 ) return; err_when( inn_unit_count >= MAX_INN_UNIT ); //--------- add the InnUnit --------// InnUnit *innUnit = inn_unit_array+inn_unit_count; memset( innUnit, 0, sizeof(InnUnit) ); inn_unit_count++; //--------- set InnUnit vars -----------------// innUnit->unit_id = unitPtr->unit_id; innUnit->skill = unitPtr->skill; innUnit->hit_points = unitPtr->hit_points; innUnit->hero_id = unitPtr->hero_id; unitPtr->hero_id = 0; innUnit->unique_id = unitPtr->unique_id; innUnit->item = unitPtr->item; unitPtr->item.clear(); int spyRecno = innUnit->spy_recno = unitPtr->spy_recno; spy_array[spyRecno]->set_place(SPY_FIRM, firm_recno); unitPtr->spy_recno = 0; // prevent Unit::deinit call spy_array.del_spy innUnit->set_hire_cost(); innUnit->stay_count = 10 + misc.random(5); unitPtr->deinit_sprite(); unit_array.disappear_in_firm(unitRecno); }
//-------- Begin of function FirmInn::transfer_inn_unit --------// // int FirmInn::transfer_inn_unit(int recNo) { err_when( recNo < 1 ); if( recNo > inn_unit_count ) return 0; InnUnit *innUnit = inn_unit_array+recNo-1; if( !innUnit->spy_recno ) return 0; // only spy considers transfer Spy *spyPtr = NULL; if( innUnit->spy_recno && !spy_array.is_deleted(innUnit->spy_recno) ) spyPtr = spy_array[innUnit->spy_recno]; // -------- scan any inn firm in world ----------// int ownFirmRecno = 0; int anyOwnInn = 0; int firmRecno = 1+misc.random(firm_array.size()); int firmCount; for( firmCount = firm_array.size(); firmCount > 0; --firmCount, ++firmRecno ) { if( firmRecno > firm_array.size() ) firmRecno -= firm_array.size(); err_when(firmRecno < 1 || firmRecno > firm_array.size()); if( firm_array.is_deleted(firmRecno) ) continue; FirmInn *firmInn = firm_array[firmRecno]->cast_to_FirmInn(); if( !firmInn ) continue; if( spyPtr && firmInn->nation_recno == spyPtr->true_nation_recno ) { if( !anyOwnInn ) anyOwnInn = firmRecno; } if( firmRecno == firm_recno ) // never go back to the same inn continue; if( firmInn->inn_unit_count >= MAX_INN_UNIT ) continue; if( spyPtr && firmInn->nation_recno == spyPtr->true_nation_recno ) { if( !ownFirmRecno ) ownFirmRecno = firmRecno; continue; // spy tend not to go back to own firmInn, unless no other choice } break; } if( firmCount <= 0 ) // if no other firm found, go back to own firm firmRecno = ownFirmRecno; if( firmRecno ) // if no any firm to go return false { // ------ transfer inn unit -------// FirmInn *firmInn = firm_array[firmRecno]->cast_to_FirmInn(); err_when( !firmInn ); InnUnit *newInnUnit = firmInn->inn_unit_array + firmInn->inn_unit_count; firmInn->inn_unit_count++; *newInnUnit = *innUnit; // ------- generate new stay count ------// newInnUnit->stay_count = 10 + misc.random(5); newInnUnit->set_hire_cost(); // ------ trasfer Spy ------- // if( spyPtr ) spyPtr->set_place(SPY_FIRM, firmRecno); innUnit->spy_recno = 0; // prevent del_inn_unit call spy_array.del_spy // ------ delete inn unit of current inn ------// del_inn_unit(recNo); innUnit = newInnUnit; // set innUnit to the transferred place for later use } else if( (firmRecno = anyOwnInn) ) { // mobilize in another any own inn hire( recNo, 1, firmRecno ); innUnit = NULL; } return firmRecno; }
void FirmInn::add_inn_unit(int raceId) { err_when( inn_unit_count >= MAX_INN_UNIT ); InnUnit *innUnit = inn_unit_array+inn_unit_count; RaceInfo *raceInfo = race_res[raceId]; int spyFlag = 0; // must determine before inn_unit_count increase if( count_soldier() >= MAX_INN_UNIT/2 ) spyFlag = 1; else if( count_spy() >= MAX_INN_UNIT/2 ) spyFlag = 0; else spyFlag = misc.random(2); memset( innUnit, 0, sizeof(InnUnit) ); inn_unit_count++; //---- determine whether the unit is a spy or a military unit ----// if( !spyFlag ) // a military unit { //------- create a unit now -----------// int unitRecno; if( misc.random(20)==0 ) // 5% have a hero { unitRecno = hero_res.create_hero( -1, -1, 0, 0, 0, 0, 1); // -1 - create the unit as an invisible unit } // last 1 - the heroes are for hire, check the HeroInfo::for_hire before adding it else //---- just create a unit, not a hero -----// { int unitId; int heroPower = 20 + misc.random(20); if( misc.random(2)==0 ) unitId = raceInfo->infantry_unit_id; else unitId = raceInfo->special_unit_id; unitRecno = hero_res.create_powerful_unit( -1, -1, 0, unitId, heroPower); // -1 - create the unit as an invisible unit } //--------------------------------------// if( !unitRecno ) { inn_unit_count--; return; } //--------------------------------------// Unit* unitPtr = unit_array[unitRecno]; err_when( !unitPtr->unit_id ); innUnit->hero_id = unitPtr->hero_id; innUnit->unit_id = unitPtr->unit_id; innUnit->skill = unitPtr->skill; innUnit->hit_points = unitPtr->hit_points; innUnit->item = unitPtr->item; unitPtr->item.clear(); unit_array.del(unitRecno); // delete the unit as it was created temporarily for setting skill and item values } else // a spy { switch( misc.random(3) ) { case 0: // civilian spy innUnit->unit_id = (char) raceInfo->civilian_unit_id; innUnit->skill.init(innUnit->unit_id, CITIZEN_COMBAT_LEVEL, 0); innUnit->spy_skill = 30+misc.random(40); break; case 1: // infantry spy innUnit->unit_id = (char) raceInfo->infantry_unit_id; innUnit->skill.init(innUnit->unit_id, 20+misc.random(30), 20+misc.random(30)); // a spy also have leadership and combat ability, but lower than units with leadership as their main skills innUnit->spy_skill = 30+misc.random(40); break; case 2: // special unit spy innUnit->unit_id = (char) raceInfo->special_unit_id; innUnit->skill.init(innUnit->unit_id, 30+misc.random(30), 10+misc.random(20)); // a spy also have leadership and combat ability, but lower than units with leadership as their main skills innUnit->spy_skill = 30+misc.random(40); break; default: err_here(); } if( misc.random(4)==0 ) innUnit->spy_skill += misc.random(30); else if( misc.random(2)==0 ) innUnit->spy_skill += misc.random(15); } err_when( !innUnit->unit_id ); // ------ randomly assign a unique id --------// // ###### begin Gilbert 23/2 ######// innUnit->unique_id = misc.rand_long(); // ###### end Gilbert 23/2 ######// // ------ set current hit point -------// innUnit->hit_points = (float) innUnit->max_hit_points(); //-------------------------------------------// innUnit->set_hire_cost(); innUnit->stay_count = 10 + misc.random(5); }