//--------- Begin of function FirmCamp::next_day ---------// // void FirmCamp::next_day() { //----- call next_day() of the base class -----// Firm::next_day(); //----- update the patrol_unit_array -----// validate_patrol_unit(); validate_soldier(); //------- update loyalty --------// if( info.game_date%30 == firm_recno%30 ) update_loyalty(); //-------- consume food --------// if( soldier_count>0 ) consume_food(); // ------- process train ---------// if( config.fast_build && is_own() ) { for( int i=0 ; i<100 ; i++ ) basic_train(); } else basic_train(); //--------------------------------------// if( info.game_date%30 == firm_recno%30 ) // once a week { advanced_train(); } if( info.game_date%8 == firm_recno%8 ) { recover_hit_point(); } // ------ process item --------// Soldier* soldierPtr = soldier_array; for( int i=0 ; i<soldier_count ; i++, soldierPtr++ ) { soldierPtr->item.next_day(); } //----------- debugging code -----------// err_when( overseer_recno && unit_array[overseer_recno]->skill_level()==0 ); err_when( overseer_recno && unit_array[overseer_recno]->nation_recno != nation_recno ); }
//--------- Begin of function Unit::next_day ---------// // void Unit::next_day() { int unitRecno = sprite_recno; err_when( unit_array.is_deleted(unitRecno) ); err_when( race_id && !is_visible() && unit_mode==0 ); err_when( team_info && !mem.get_mem_size(team_info) ); // ##### begin Gilbert 2/3 #####// err_when( race_id && unit_id != UNIT_WAGON && !name_id ); // ##### end Gilbert 2/3 #####// //------- functions for non-independent nations only ------// if( nation_recno ) { pay_expense(); if( unit_array.is_deleted(unitRecno) ) // if its hit points go down to 0, is_deleted() will return 1. return; //------- update loyalty -------------// if( info.game_date%30 == sprite_recno%30 ) { update_loyalty(); err_when( unit_array.is_deleted(unitRecno) ); } //------- think about rebeling -------------// if( info.game_date%15 == sprite_recno%15 ) { if( think_betray() ) return; } } //------- recover from damage -------// if( info.game_date%4 == sprite_recno%4 ) // recover points per 4 days { process_recover(); err_when( unit_array.is_deleted(unitRecno) ); } //------- restore cur_power --------// cur_power += 5; if( cur_power > max_power) cur_power = max_power; // ------ process magic effect ---------// if( invulnerable_day_count > 0 ) --invulnerable_day_count; //------- king undie flag (for testing games only) --------// if( config.king_undie_flag && rank_id == RANK_KING && nation_recno && !nation_array[nation_recno]->is_ai() ) { hit_points = (float) max_hit_points(); // ####### begin Gilbert 27/1 ######// if( invulnerable_day_count == 0 ) ++invulnerable_day_count; // ####### end Gilbert 27/1 ######// } //-------- if aggresive_mode is 1 --------// if( is_visible() ) think_aggressive_action(); // --------- process item -------// item.next_day(); //---------- debug ------------// #ifdef DEBUG err_when( race_id && unit_res[unit_id]->unit_class != UNIT_CLASS_HUMAN && unit_res[unit_id]->unit_class != UNIT_CLASS_MONSTER && unit_res[unit_id]->unit_class != UNIT_CLASS_WAGON ); if( unit_mode == UNIT_MODE_CONSTRUCT_TOWN ) err_when( town_array[unit_mode_para]->builder_recno != sprite_recno ); err_when( unit_mode==UNIT_MODE_REBEL && nation_recno ); // rebels must be independent //------ debug: spy ----------// if( spy_recno ) { err_when( spy_array.is_deleted(spy_recno) ); Spy* spyPtr = spy_array[spy_recno]; err_when( nation_recno != spyPtr->cloaked_nation_recno ); if( unit_mode == UNIT_MODE_OVERSEE ) { err_when( spyPtr->spy_place != SPY_FIRM ); err_when( spyPtr->spy_place_para != unit_mode_para ); } else { err_when( spyPtr->spy_place != SPY_MOBILE ); err_when( spyPtr->spy_place_para != sprite_recno ); } // ####### begin Gilbert 24/2 ########// err_when( unique_id != spyPtr->unique_id ); // ####### end Gilbert 24/2 ########// } //------ debug: team ----------// if( leader_unit_recno ) { Unit* unitPtr = unit_array[leader_unit_recno]; err_when( unitPtr->rank_id != RANK_GENERAL && unitPtr->rank_id != RANK_KING ); } err_when( (rank_id == RANK_GENERAL || rank_id == RANK_KING) && !team_info ); if( team_info ) { for( int i=0 ; i<team_info->member_count ; i++ ) { Unit* unitPtr = unit_array[team_info->member_unit_array[i]]; if( unitPtr->sprite_recno == sprite_recno ) // the same unit continue; err_when( unitPtr->leader_unit_recno != sprite_recno ); } } if( leader_unit_recno && unit_mode != UNIT_MODE_REBEL ) // in rebel mode, the leader_unit_recno is not linked to team_info { Unit* leaderUnit = unit_array[leader_unit_recno]; err_when( !leaderUnit->team_info ); for( int i=0 ; i<leaderUnit->team_info->member_count ; i++ ) { if( leaderUnit->team_info->member_unit_array[i] == sprite_recno ) break; } err_when( i==leaderUnit->team_info->member_count ); // not found err_when( unit_array.is_truly_deleted(leader_unit_recno) ); err_when( unit_array[leader_unit_recno]->nation_recno != nation_recno ); // err_when( unit_array[leader_unit_recno]->team_id != team_id ); } //------ debug: AI action ----------// if( cur_order.ai_action_id ) { Nation* nationPtr = nation_array[nation_recno]; for( int actionRecno=nationPtr->action_count() ; actionRecno>0 ; actionRecno-- ) { if( nationPtr->is_action_deleted(actionRecno) ) continue; ActionNode* actionNode = nationPtr->get_action(actionRecno); if( cur_order.ai_action_id == actionNode->action_id ) { err_when( actionNode->processing_instance_count<1 ); break; } } } //---------------------------------// err_when( hit_points > max_hit_points() ); err_when( max_hit_points() == 0 ); err_when( combat_level()<0 ); err_when( combat_level()>1000 ); err_when( unit_mode==UNIT_MODE_REBEL && spy_recno ); // no rebel spies err_when( unit_mode==UNIT_MODE_REBEL && nation_recno ); // all rebels must be independent units err_when( unit_mode==UNIT_MODE_TOWN_DEFENDER && spy_recno ); // no rebel spies err_when( loyalty < 0 || loyalty > 100 ); err_when( nation_contribution < 0 ); err_when( nation_contribution > MAX_NATION_CONTRIBUTION ); err_when( is_ai && ( !nation_recno || !nation_array[nation_recno]->is_ai() ) ); #else // fix bug on fly in the release version // ######## begin Gilbert 5/2 #####// // if( combat_level() > skill.max_combat_level ) // combat_level() = skill.max_combat_level; if( skill.actual_combat_level(NULL) > skill.max_combat_level ) // raw combat level set_combat_level( skill.max_combat_level ); // ######## end Gilbert 5/2 #####// #endif }
//--------- Begin of function Unit::betray ---------// // // If this unit is a spy, this function betray() will be // called by Unit::spy_change_nation() or Firm::capture_firm(). // // If this is not a spy, this function will only be called // by think_betray() and other nation deinit functions. // int Unit::betray(int newNationRecno) { //----- if this is a spy, call spy_change_nation -----// if( spy_recno && spy_array[spy_recno]->cloaked_nation_recno != newNationRecno ) // cloaked_nation_recno == newNationRecno if betray() is called by spy_change_nation() already { spy_change_nation(newNationRecno, COMMAND_AUTO); return 1; } //-------------------------------// err_when( newNationRecno && nation_array[newNationRecno]->is_human() && // monsters in firms should not betray to humans is_monster() && unit_mode == UNIT_MODE_OVERSEE ); int unitRecno = sprite_recno; err_when( unit_array.is_truly_deleted(unitRecno) ); err_when( rank_id == RANK_KING ); if( nation_recno == newNationRecno ) return 0; if( unit_mode == UNIT_MODE_CONSTRUCT_FIRM || // don't change nation when the unit is constructing a firm unit_mode == UNIT_MODE_CONSTRUCT_TOWN || unit_mode == UNIT_MODE_ON_SHIP ) // don't change nation when the unit is constructing a firm { return 0; } //--- special case: units in Monster Fortress cannot change nation ---// if( unit_mode == UNIT_MODE_OVERSEE && firm_array[unit_mode_para]->firm_id == FIRM_FORTRESS ) { return 0; } //---------- add news -----------// if( nation_recno == nation_array.player_recno || newNationRecno == nation_array.player_recno ) { //--- if this is a spy, don't display news message for betrayal as it is already displayed in Unit::spy_change_nation() ---// if( !spy_recno ) news_array.unit_betray(sprite_recno, newNationRecno); } //------ change nation now ------// err_when( unit_array.is_truly_deleted(unitRecno) ); change_nation(newNationRecno); err_when( unit_array.is_truly_deleted(unitRecno) ); //-------- set the loyalty of the unit -------// if( nation_recno ) { Nation* nationPtr = nation_array[nation_recno]; loyalty = UNIT_BETRAY_LOYALTY + 10 + m.random(20); if( nationPtr->reputation > 0 ) change_loyalty( (int) nationPtr->reputation ); if( race_res.is_same_race( nationPtr->race_id, race_id ) ) change_loyalty( 30 ); err_when( loyalty < 0 || loyalty > 100 ); update_loyalty(); // update target loyalty } else //------ if change to independent rebel -------// { loyalty = 0; // no loyalty needed } //--- if this unit is a general, change nation for the units he commands ---// if( rank_id==RANK_GENERAL ) { err_when( !team_info ); for( int i=0 ; i<team_info->member_count ; i++ ) { int memberUnitRecno = team_info->member_unit_array[i]; if( memberUnitRecno == unitRecno ) // this is the unit itself continue; Unit* unitPtr = unit_array[memberUnitRecno]; if( !unitPtr->is_visible() ) continue; if( unitPtr->spy_recno ) // if the unit is a spy unitPtr->spy_change_nation(newNationRecno, COMMAND_AUTO); else unitPtr->change_nation(newNationRecno); } } err_when( unit_array.is_truly_deleted(unitRecno) ); //------ go to meet the new master -------// if( is_visible() && nation_recno ) { if( !spy_recno || spy_array[spy_recno]->notify_cloaked_nation_flag ) { if( is_civilian() ) ai_move_to_nearby_town(); else ai_move_to_nearby_firm(FIRM_CAMP, FIRM_FORT); } } err_when( unit_array.is_truly_deleted(unitRecno) ); return 1; }
//--------- Begin of function Unit::init ---------// // // <int> unitId - the id. of the unit // <int> nationRecno - the recno of nation // [int] rankId - rank id. of the unit (none for non-human unit) // [int] unitLoyalty - loyalty of the unit (none for non-human unit) // [int] startXLoc, startYLoc - the starting location of the unit // (if startXLoc < 0, this is a unit for hire, and is not a unit of the game yet. init_sprite() won't be called for this unit) // (default: -1, -1) // // Note: sprite_recno must be initialized first before calling Unit::init() // void Unit::init(int unitId, int nationRecno, int rankId, int unitLoyalty, int startXLoc, int startYLoc) { //------------ set basic vars -------------// nation_recno = (char) nationRecno; rank_id = rankId; // rank_id must be initialized before init_unit_id() as init_unit_id() may overwrite it if( rank_id == RANK_GENERAL || rank_id == RANK_KING ) { err_when( team_info ); team_info = (TeamInfo*) mem_add( sizeof(TeamInfo) ); memset( team_info, 0, sizeof(TeamInfo) ); } init_unit_id(unitId); race_id = (char) unit_res[unit_id]->race_id; //------- init unit name ---------// if( is_human() && unit_id != UNIT_WAGON ) { name_id = race_res[race_id]->get_new_name_id(); } else if( is_monster() ) { name_id = monster_res.get_new_name_id(); } else //---- init non-human unit series no. ----// { if( nation_recno ) name_id = ++nation_array[nation_recno]->last_unit_name_id_array[unit_id-1]; else name_id = 0; } // ###### begin Gilbert 23/2 ######// unique_id = misc.rand_long(); // ###### end Gilbert 23/2 ######// //---------- init other vars ----------// err_when( unitLoyalty < 0 || unitLoyalty > 100 ); loyalty = unitLoyalty; // ##### begin Gilbert 29/5 ########// if( is_die_after_attack() ) // behavior_mode = UNIT_STAND_GROUND; // bee die after attack, so don't waste his life behavior_mode = UNIT_DEFENSIVE; // bee die after attack, so don't waste his life else behavior_mode = UNIT_AGGRESSIVE; // the default mode is aggressive // ##### end Gilbert 29/5 ########// //--------- init skill, and skill potential ---------// skill.init(unit_id, 100); set_combat_level(-1); hit_points = (float) max_hit_points(); //------ initialize the base Sprite class -------// if( startXLoc >= 0 ) init_sprite( startXLoc, startYLoc ); else cur_x = -1; //-------------- update loyalty -------------// update_loyalty(); //--------------- init AI info -------------// init_ai(); //----------- init derived class ----------// init_derived(); set_combat_level(-1); }