//---------- Begin of function Firm::process_repair --------// // void Firm::process_repair() { if( repair_flag && hit_points < max_hit_points() && info.game_date > last_attack_date+1 ) // can only do construction when the firm is not under attack // { if( nation_recno ) { Nation* nationPtr = nation_array[nation_recno]; float repairCost = (float) firm_res[firm_id]->setup_cost * REPAIR_POINTS_PER_DAY / max_hit_points(); float repairLiveCost = (float) firm_res[firm_id]->setup_live_points_cost * REPAIR_POINTS_PER_DAY / max_hit_points(); if( nationPtr->cash < repairCost || nationPtr->live_points < repairLiveCost ) return; nationPtr->add_expense( EXPENSE_CONSTRUCTION, repairCost, 1 ); nationPtr->change_live_points( -repairLiveCost ); } hit_points += REPAIR_POINTS_PER_DAY; if( hit_points >= max_hit_points() ) { hit_points = (float) max_hit_points(); set_repair_flag( 0, COMMAND_AUTO ); } } }
//---------- Begin of function Firm::process_construction --------// // void Firm::process_construction() { if( !under_construction ) return; //--- can only do construction when the firm is not under attack ---// if( info.game_date <= last_attack_date+1 ) return; if( sys.frame_count%2!=0 ) // one build every 2 frames return; //------ increase the construction progress ------// Unit *unitPtr = NULL; // builder may be missing if built by scenario editor if( builder_recno ) { unitPtr = unit_array[builder_recno]; hit_points+=2; if( config.fast_build && nation_recno==nation_array.player_recno ) hit_points += 10; } //------- when the construction is complete ----------// if( hit_points >= max_hit_points() ) // finished construction { hit_points = (float) max_hit_points(); under_construction = 0; setup_date = info.game_date; // ##### begin Gilbert 15/10 ######// if( unitPtr && nation_recno == nation_array.player_recno ) se_res.far_sound(center_x, center_y, 1, 'S', unitPtr->sprite_id, "FINS", 'F', firm_id); // ##### end Gilbert 15/10 ######// err_when(builder_recno<=0 || unit_array.is_deleted(builder_recno)); err_when(unitPtr->nation_recno!=nation_recno); //---------------------------------------// // ##### begin Gilbert 15/10 ######// if( builder_recno && builder_stay_after_construction() ) // attempt to assign the unit into the firm. return 1 if assigned successfully // ##### end Gilbert 15/10 ######// builder_recno = 0; else set_builder(0); // if cannot assign it to the firm, mobilize it. } err_when (hit_points < 0 || hit_points > max_hit_points() ); }
//--------- Begin of function Unit::change_hit_points ---------// // void Unit::change_hit_points(float changePoints) { hit_points += changePoints; if( hit_points < 0 ) hit_points = (float) 0; if( hit_points > max_hit_points() ) hit_points = (float) max_hit_points(); }
//--------- Begin of function Unit::set_combat_level ---------// // // <int> combatLevel new combat level or -1 for current combat level // so as to update unit attribute of that combat level void Unit::set_combat_level(int combatLevel) { // ##### begin Gilbert 4/11 ######// if( combatLevel == -1 ) // update unit attribute of that combat level combatLevel = skill.actual_combat_level(NULL); // get original combat // ##### end Gilbert 4/11 ######// err_when( combatLevel<=0 || combatLevel>1000 ); int oldMaxHitPoints = max_hit_points(); skill.set_combat_level(combatLevel); // it will affect max_hit_points() hit_points = hit_points * max_hit_points() / oldMaxHitPoints; hit_points = min(hit_points, max_hit_points()); // --------- update can_guard_flag -------// // ##### begin Gilbert 4/11 #######// if( combat_level() >= unit_res[unit_id]->guard_combat_level) // ##### end Gilbert 4/11 #######// { can_guard_flag = sprite_info->can_guard_flag; } else { can_guard_flag = 0; } if( combat_level() <= MAX_COMBAT_TRAIN ) max_power = combat_level() + 50; else max_power = combat_level() / 10 + ( MAX_COMBAT_TRAIN + 50 - MAX_COMBAT_TRAIN / 10 ); // ###### patch begin Gilbert 17/2 #####// // if( race_id == RACE_VIKING && nation_recno // && god_res[GOD_VIKING]->nation_prayer_count(nation_recno) > 0 ) if( nation_recno && god_res[GOD_VIKING]->nation_prayer_count(nation_recno) > 0 ) { // max_power += 20; max_power += 25; } // ###### patch end Gilbert 17/2 #####// cur_power = min(cur_power, max_power); }
//------- Begin of function Firm::complete_construction -----------// // // Complete construction instantly. // void Firm::complete_construction() { if( under_construction ) { hit_points = (float) max_hit_points(); under_construction = 0; setup_date = info.game_date; } }
//------- Begin of function Firm::being_killed ------// // // <BaseObj*> attackerObj - this can be NULL if the attacker no longer // exists (the damage is caused by a bullet.) // void Firm::being_killed(BaseObj* attackerObj) { se_res.sound(center_x, center_y, 1, 'F', firm_id, "DIE" ); if( nation_recno == nation_array.player_recno && attackerObj ) //BUGHERE news_array.firm_destroyed(firm_recno, attackerObj); // ######## begin Gilbert 17/6 ########// if( nation_recno == 0 && firm_id == FIRM_LAIR && is_monster() ) { news_array.monster_firm_destroyed( monster_id(), center_x, center_y ); } // ######## end Gilbert 17/6 ########// if( nation_recno ) { if( attackerObj && attackerObj->nation_recno ) nation_array[attackerObj->nation_recno]->enemy_firm_destroyed++; if( nation_recno ) nation_array[nation_recno]->own_firm_destroyed++; } //-----------------------------------------// if( attackerObj && attackerObj->nation_recno ) { Nation* attackerNation = nation_array[attackerObj->nation_recno]; //-- destroying a monster firm raise the attacking nation's reputation --// if( is_monster() ) { float repIncrease = (float) max_hit_points() / 600; //-- if the lair is enslaving the towns, increase the reputation bonus --// if( cast_to_FirmLair() ) { int tributeAmount = cast_to_FirmLair()->collect_town_tribute(0); repIncrease += (float) tributeAmount / 600; } attackerNation->change_reputation(repIncrease); //--- when destroying an enslaving Fryhtan lair, the independent towns enslaved by it will reduce its resistance towards you by 30 points ---// if( cast_to_FirmLair() ) { int i; Town* townPtr; for( i=0 ; i<linked_town_count ; i++ ) { if(town_array.is_deleted(linked_town_array[i])) continue; townPtr = town_array[linked_town_array[i]]; //--- if it is a linked independent town ---// if( townPtr->nation_recno == 0 && // ####### begin Gilbert 9/3 ########// nation_recno && // ####### end Gilbert 9/3 ########// townPtr->resistance(nation_recno) < MONSTER_COLLECT_TOWN_TRIBUTE_LOYALTY ) { townPtr->change_resistance(attackerObj->nation_recno, -30); } } } } //------ destroyng a building gives money ------// float killMoney = (float) (firm_res[firm_id]->setup_cost + firm_recno%100) / 3; // add some randomness attackerNation->add_income( INCOME_TREASURE, killMoney ); attackerNation->increased_cash = killMoney; } firm_array.del_firm(firm_recno); }
void FirmOffensive2::put_info(int refreshFlag) { if( !should_show_info() ) return; vga.active_buf->put_bitmap( INFO_X1, INFO_Y1, image_gameif.read("MISSBASE") ); int hitPoints; String str; int offsetX = 0; int offsetY = 0; if( hit_points > (float)0 && hit_points < (float)1 ) hitPoints = 1; // display 1 for value between 0 and 1 else hitPoints = (int) hit_points; if ( max_hit_points() ) { offsetX = -35; offsetY = -14; short* hitPointBitmap =NULL; int ratio = hitPoints *40 / (int)max_hit_points(); int size = hitPoints *76 / (int)max_hit_points(); //106 x 35 --- 15 to 90 ie. 0 to 40 hitPointBitmap = (short *)mem_add( BitmapW::size(15 +size, 35) ); if (ratio <11) vga.active_buf->put_bitmap_trans( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, image_spict.read("MTR_B2")); else if (ratio <40) vga.active_buf->put_bitmap_trans( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, image_spict.read("MTR_B3")); else vga.active_buf->put_bitmap_trans( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, image_spict.read("MTR_B4")); vga.active_buf->read_bitmapW( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, INFO_X1 +94 +20 +size +offsetX, INFO_Y1 +80 +offsetY, hitPointBitmap ); vga.active_buf->put_bitmap_trans( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, image_spict.read("MTR_B1")); vga.active_buf->put_bitmapW( INFO_X1 +80 +20 +offsetX, INFO_Y1 +49 +offsetY, hitPointBitmap ); mem_del( hitPointBitmap ); font_whbl.center_put( INFO_X1 +43, INFO_Y1 +45, INFO_X1 +65, INFO_Y1 +57, m.format((int)hitPoints,4)); font_whbl.center_put( INFO_X1 +169, INFO_Y1 +45, INFO_X1 +191, INFO_Y1 +57, m.format((int)max_hit_points(),4) ); } // font_whbl.center_put( INFO_X1 +12, INFO_Y1 +9, INFO_X2, INFO_Y1 +21, "Offensive Building 3", 0, 1 ); font_whbl.center_put( INFO_X1 +12, INFO_Y1 +9, INFO_X2, INFO_Y1 +21, firm_name(), 0, 1 ); FirmBuild* firmBuild = firm_res.get_build(firm_build_id); short *colorRemapTable = firmBuild->get_color_remap_table(nation_recno, firm_array.selected_recno == firm_recno); colorRemapTable = firm_res.calc_color_remap_table( colorRemapTable, 1.0f ); FirmBitmap* firmBitmap = firm_res.get_bitmap(firmBuild->first_bitmap(1)); if( firmBitmap ) { Bitmap* bitmapPtr = (Bitmap *) firmBuild->res_bitmap.read_imported(firmBitmap->bitmap_ptr); int x1; int y1; int srcX2; int srcY2; if (config.building_size == 1) { x1 = INFO_X1 +130; y1 = INFO_Y1 +140; } else { x1 = INFO_X1 +120; y1 = INFO_Y1 +142; } x1 += firmBitmap->offset_x; y1 += firmBitmap->offset_y; int x2 = x1 + bitmapPtr->get_width() -1; int y2 = y1 + bitmapPtr->get_height() -1; int srcX1 = max(x1, INFO_X1+15)-x1; int srcY1 = 0; if (config.building_size == 1) { srcX2 = min(x2, INFO_X2)-x1; srcY2 = min(y2, INFO_Y1+227)-y1; } else { srcX2 = min(x2, INFO_X2)-x1; srcY2 = min(y2, INFO_Y2)-y1; } vga.active_buf->put_bitmap_area_trans_remap_decompress(x1, y1, (char *) bitmapPtr, srcX1, srcY1, srcX2, srcY2, colorRemapTable); } /* if (config.building_size == 1) return; firmBitmap = firm_res.get_bitmap(firmBuild->first_bitmap(firm_cur_frame[0])); if( firmBitmap && firmBitmap->display_layer == 1 ) { Bitmap* bitmapPtr = (Bitmap *) firmBuild->res_bitmap.read_imported(firmBitmap->bitmap_ptr); int x1 = INFO_X1 +120 +firmBitmap->offset_x; int y1 = INFO_Y1 +142 +firmBitmap->offset_y; int x2 = x1 + bitmapPtr->get_width() -1; int y2 = y1 + bitmapPtr->get_height() -1; int srcX1 = max(x1, INFO_X1+15)-x1; int srcY1 = 0; int srcX2 = min(x2, INFO_X2)-x1; int srcY2 = min(y2, INFO_Y2)-y1; vga.active_buf->put_bitmap_area_trans_remap_decompress(x1, y1, (char *) bitmapPtr, srcX1, srcY1, srcX2, srcY2, colorRemapTable); // vga_back.put_bitmap_trans_remap_decompress(INFO_X1 +113 +firmBitmap->offset_x, // INFO_Y1 +158 +firmBitmap->offset_y, bitmapPtr, colorRemapTable); }*/ }
//--------- 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::process_recover ---------// // void Unit::process_recover() { if( hit_points==0.0f || hit_points == max_hit_points() ) // this unit is dead already return; err_when( hit_points > max_hit_points() ); #define RECOVER_SLOW_DOWN 0.5f //---- overseers in firms and ships in harbors recover faster ----// float hitPointsInc = 0.0f; if( unit_mode == UNIT_MODE_OVERSEE || unit_mode == UNIT_MODE_IN_HARBOR ) { hitPointsInc = 2.0f * RECOVER_SLOW_DOWN; } //------ for units on ships --------// else if( unit_mode == UNIT_MODE_ON_SHIP ) { //--- if the ship where the unit is on is in the harbor, the unit recovers faster ---// if( unit_array[unit_mode_para]->unit_mode == UNIT_MODE_IN_HARBOR ) hitPointsInc = 2.0f * RECOVER_SLOW_DOWN; else hitPointsInc = 1.0f * RECOVER_SLOW_DOWN; } //----- only recover when the unit is not moving -----// else if( cur_action == SPRITE_IDLE ) { hitPointsInc = 1.0f * RECOVER_SLOW_DOWN; } else hitPointsInc = 0; // --------- recovery bonus --------// if( hitPointsInc > 0.0f ) { // high max_hit_points recover faster hitPointsInc += RECOVER_SLOW_DOWN * max_hit_points() / 200; } // ------- bonus from item ---------// hitPointsInc += RECOVER_SLOW_DOWN * item.ability(ITEM_ABILITY_RECOVERY); //---------- recover now -----------// if( hitPointsInc > 0 ) { hit_points += hitPointsInc; if( hit_points > max_hit_points() ) hit_points = (float) max_hit_points(); } }
//---------- Begin of function Firm::next_day --------// // void Firm::next_day() { if( !nation_recno ) return; #ifdef DEBUG //BUGHERE err_when( is_human() == (firm_id >= FIRM_LAIR && firm_id <= FIRM_MAGIC) ); // error when a human attempts to build a monster firm or a mosnter attempts to build a human firm //------ validate linked towns ------// int lastLinkedTown=0; for( int i=0 ; i<linked_town_count ; i++ ) { Town* townPtr = town_array[linked_town_array[i]]; err_when( townPtr->town_recno == lastLinkedTown ); lastLinkedTown = townPtr->town_recno; int j; for( j=0; j<townPtr->linked_firm_count ; j++ ) { if( townPtr->linked_firm_array[j] == firm_recno ) break; } err_when( j==townPtr->linked_firm_count ); // the link is brokwn, only one side has it } #endif //------ think about updating link status -------// // // This part must be done here instead of in // process_ai() because it will be too late to do // it in process_ai() as the next_day() will call // first and some wrong goods may be input to markets. // //-----------------------------------------------// if( is_ai ) { if( info.game_date%30==firm_recno%30 || !ai_link_checked ) // once 30 days or when the link has been changed. { ai_update_link_status(); ai_link_checked = 1; } } //-------- pay expenses ----------// pay_expense(); //--------- repairing ----------// process_repair(); //------ catching spies -------// if( info.game_date%30 == firm_recno%30 ) spy_array.catch_spy(SPY_FIRM, firm_recno); //--- recheck no_neighbor_space after a period, there may be new space available now ---// if( no_neighbor_space && info.game_date%180 == firm_recno%180 ) { short buildXLoc, buildYLoc; if( nation_array[nation_recno]->find_best_place_loc(FIRM_INN, loc_x1, loc_y1, buildXLoc, buildYLoc) ) // whether it's FIRM_INN or not really doesn't matter, just any firm type will do no_neighbor_space = 0; } // ##### begin Gilbert 16/11 #######// // ------ reset active_link_town_recno if deleted --------// if( town_array.is_deleted(active_link_town_recno) ) { active_link_town_recno = 0; } // ##### end Gilbert 16/11 #######// // ####### begin Gilbert 4/3 ########// // ------ clear rally destination if deleted -------// if( rally_enable_flag && rally_dest_base_obj_recno && base_obj_array.is_deleted(rally_dest_base_obj_recno) ) { clear_rally_point(COMMAND_AUTO); } // ####### end Gilbert 4/3 ########// if( hit_points < (max_hit_points() * 0.1)) { if (misc.random(100) > 20) { FirmDie firmDieFire1; firmDieFire1.init(this, 3, misc.random(100)); firm_die_array.add(&firmDieFire1); } if (misc.random(100) > 40) { FirmDie firmDieFire2; firmDieFire2.init(this, 3, misc.random(100)); firm_die_array.add(&firmDieFire2); } // if (misc.random(100) > 30) // bullet_array.add_bullet(this, this); } else if( hit_points < (max_hit_points() * 0.3)) { if (misc.random(100) > 30) { FirmDie firmDieFire3; firmDieFire3.init(this, 3, misc.random(100)); firm_die_array.add(&firmDieFire3); } // if (misc.random(100) > 20) // bullet_array.add_bullet(this, this); } }
//---------- Begin of function Firm::process_animation --------// // void Firm::process_animation() { //-------- process animation ----------// FirmBuild* firmBuild = firm_res.get_build(firm_build_id); FirmBitmap* firmBitmap; int frameCount = firmBuild->frame_count; int firstBitmap; int bitmapCount; if( hit_points < (max_hit_points() * 0.1)) { if (misc.random(100) > 65) { int effectId = sprite_res.search_sprite( "FIRMDIE" ); if( effectId ) { Effect::create(effectId, (loc_x1 + misc.random(20)%(loc_x2 -loc_x1 +1)) *LOCATE_WIDTH, (loc_y1 + misc.random(20)%(loc_y2 -loc_y1 +1)) *LOCATE_HEIGHT, SPRITE_DIE, 1, 2, 0); } } } else if( hit_points < (max_hit_points() * 0.3)) { if (misc.random(100) > 80) { int effectId = sprite_res.search_sprite( "FIRMDIE" ); if( effectId ) { Effect::create(effectId, (loc_x1 + misc.random(20)%(loc_x2 -loc_x1 +1)) *LOCATE_WIDTH, (loc_y1 + misc.random(20)%(loc_y2 -loc_y1 +1)) *LOCATE_HEIGHT, SPRITE_DIE, 1, 2, 0); } } } if( frameCount==1 ) // no animation for this firm return; //---------- next frame -----------// int aniPartCount = firmBuild->ani_part_count; for (int i = 0; i < aniPartCount ; i++) { firm_remain_frame_delay[i] --; if (firm_remain_frame_delay[i] < 0) { // animate_full_size only supports animation of looping // it does not support random animation and in fact // it is now only used for no animation buildings // but it support different frame different delay if( firmBuild->animate_full_size ) { if( ++firm_cur_frame[i] > frameCount ) firm_cur_frame[i] = 1; firm_remain_frame_delay[i] = (char) firmBuild->frame_delay(firm_cur_frame[i]); } else { // not animate_full_size supports animation of looping and // random animation and partial animation // however different frames of each parts must has same delay for ( int k=1; k <frameCount; k++ ) { firstBitmap = firmBuild->first_bitmap(k+1); bitmapCount = firmBuild->bitmap_count(k+1); int j; for ( j=0; j <bitmapCount; j++ ) { firmBitmap = firm_res.get_bitmap(firstBitmap + j); if( firmBitmap ) { if (firmBitmap->ani_part == (i + 1)) { // unlike the animate_full_size animation, it search starting // from the 2nd frame for bitmaps (since now 1 frame may has more // than 1 bitmap) with same animation part no. of the currently // searching part no., i. This has no relationship with the // current_frame. Then restore this animation part's delay and // set its current_frame either randomly or sequentially firm_remain_frame_delay[i] = firmBitmap->delay; if (firmBitmap->random_flag) firm_cur_frame[i] = misc.random(100) % frameCount +1; else if( ++firm_cur_frame[i] > frameCount ) firm_cur_frame[i] = 1; if((firm_cur_frame[i] == 1) && !( firmBuild->use_first_frame )) firm_cur_frame[i] = 2; break; } } } if (j < bitmapCount) break; } } } } }
void Firm::sell_firm(char remoteAction) { if( !remoteAction && remote.is_enable() ) { // packet structure : <firm recno> short *shortPtr = (short *)remote.new_send_queue_msg(MSG_FIRM_SELL, sizeof(short)); *shortPtr = firm_recno; return; } //------- sell at 50% of the original cost -------// Nation* nationPtr = nation_array[nation_recno]; float sellIncome = (float) firm_res[firm_id]->setup_cost / 2 * (int) hit_points / (int) max_hit_points(); float sellLiveIncome = (float) firm_res[firm_id]->setup_live_points_cost / 2 * (int) hit_points / (int) max_hit_points(); nationPtr->add_income(INCOME_SELL_FIRM, sellIncome); if( nationPtr->is_monster() ) nationPtr->change_live_points( sellLiveIncome ); se_res.sound(center_x, center_y, 1, 'F', firm_id, "SELL" ); firm_array.del_firm(firm_recno); }
int Unit::think_general_flee() { if( force_move_flag && cur_action != SPRITE_IDLE ) // the general is already fleeing now return 1; //------- if the general is alone --------// Nation* ownNation = nation_array[nation_recno]; //------------------------------------------------// // When the general is alone and there is no assigned action OR // when the general is injured, the general will flee // back to its camp. //------------------------------------------------// if( ( team_info->member_count==0 && !cur_order.ai_action_id ) || hit_points < max_hit_points() * (75+ownNation->pref_military_courage/2) / 200 ) // 75 to 125 / 200 { //------------------------------------------// // // If the general is currently under attack, flee // to the nearest camp with the maximum protection. // //------------------------------------------// FirmCamp *firmCamp, *bestCamp=NULL; int curRating, bestRating=0; int curXLoc = next_x_loc(), curYLoc = next_y_loc(); int curRegionId = world.get_region_id( curXLoc, curYLoc ); if( cur_action == SPRITE_ATTACK ) { for( int i=ownNation->ai_camp_count-1 ; i>=0 ; i-- ) { firmCamp = firm_array[ ownNation->ai_camp_array[i] ]->cast_to_FirmCamp(); if( firmCamp->region_id != curRegionId ) continue; curRating = world.distance_rating( curXLoc, curYLoc, firmCamp->center_x, firmCamp->center_y ); if( curRating > bestRating ) { bestRating = curRating; bestCamp = firmCamp; } } } else if( home_camp_firm_recno ) // if there is a home for the general { bestCamp = firm_array[home_camp_firm_recno]->cast_to_FirmCamp(); } //------------------------------------// if( bestCamp ) { if( bestCamp->overseer_recno ) // if there is already an overseer there, just move close to the camp for protection { move( bestCamp->loc_x1, bestCamp->loc_y1 ); if( config.ai_aggressiveness > OPTION_LOW ) force_move_flag = 1; } else assign( bestCamp->loc_x1, bestCamp->loc_y1 ); } else // if the general is neither under attack or has a home camp, then call the standard think_leader_action() { think_leader_action(); } return cur_action != SPRITE_IDLE; } return 0; }
//--------- 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); }