/*
* Seven Kingdoms: Ancient Adversaries
*
* Copyright 1997,1998 Enlight Software Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
//Filename : OU_CARA2.CPP
//Description : Unit Caravan - AI functions
#include
#include
#include
#include
//------- Begin of function UnitCaravan::init_derived --------//
void UnitCaravan::init_derived()
{
last_load_goods_date = info.game_date;
}
//------- End of function UnitCaravan::init_derived --------//
//------- Begin of function UnitCaravan::process_ai --------//
//
void UnitCaravan::process_ai()
{
//-- Think about removing stops whose owner nation is at war with us. --//
if( info.game_date%30 == sprite_recno%30 );
{
if( think_del_stop() )
return;
//------ think about setting pickup goods type -----//
think_set_pick_up_type();
}
//------ Think about resigning this caravan -------//
think_resign();
}
//------- End of function UnitCaravan::process_ai --------//
//------- Begin of function UnitCaravan::think_resign --------//
int UnitCaravan::think_resign()
{
if( !is_visible() ) // can only resign when the caravan is not in a stop
return 0;
//---- resign this caravan if it has only one stop ----//
if( stop_defined_num < 2 )
{
resign(COMMAND_AI);
return 1;
}
//---- if the caravan hasn't loaded any goods for a year ----//
if( info.game_date > last_load_goods_date + 365 &&
info.game_date%30 == sprite_recno%30 ) // don't call too often as the action may fail and it takes a while to call the function each time
{
//--- don't resign if this caravan carries any goods ---//
for( int i=0 ; i 0 || product_raw_qty_array[i] > 0 )
return 0;
}
//------ resign now --------//
resign(COMMAND_AI);
return 1;
}
//--- if this caravan is travelling between two retail markets ---//
//--- (neither of them has any direct supplies) ------//
if( info.game_date%30 == sprite_recno%30 ) // don't call too often as the action may fail and it takes a while to call the function each time
{
for( int i=stop_defined_num ; i>0 ; i-- )
{
int firmRecno = stop_array[i-1].firm_recno;
if( firm_array.is_deleted(firmRecno) ||
firm_array[firmRecno]->firm_id != FIRM_MARKET )
{
del_stop(i, COMMAND_AI);
return 1;
}
//--- see if this market has any direct supply ---//
FirmMarket* firmMarket = (FirmMarket*) firm_array[firmRecno];
MarketGoods* marketGoods = firmMarket->market_goods_array;
for( int j=0 ; jsupply_30days() > 0 )
return 0;
}
}
//--- resign now if none of the linked markets have any direct supplies ---//
resign(COMMAND_AI);
return 1;
}
return 0;
}
//------- End of function UnitCaravan::think_resign --------//
//------- Begin of function UnitCaravan::think_del_stop --------//
//
// Think about removing stops whose owner nation is at war with us.
//
int UnitCaravan::think_del_stop()
{
if( !is_visible() ) // cannot del stop if the caravan is inside a market place.
return 0;
Firm* firmPtr;
Nation* nationPtr = nation_array[nation_recno];
int i;
for( i=stop_defined_num ; i>0 ; i-- )
{
int firmRecno = stop_array[i-1].firm_recno;
if( firm_array.is_deleted(firmRecno) )
{
del_stop(i, COMMAND_AI);
return 1;
}
//---- AI only knows how to trade from a market to another ------//
firmPtr = firm_array[firmRecno];
if( firmPtr->firm_id != FIRM_MARKET ||
nationPtr->get_relation(firmPtr->nation_recno)->trade_treaty==0 ) // if the treaty trade has been terminated, delete the stop
{
del_stop(i, COMMAND_AI);
return 1;
}
//--- If this market is not linked to any towns ---//
FirmMarket* firmMarket = (FirmMarket*) firm_array[stop_array[i-1].firm_recno];
if( !firmMarket->is_market_linked_to_town() )
{
//--- and the caravan is not currently picking up goods from the market ---//
int hasPickUp=0;
TradeStop* tradeStop = stop_array + i - 1;
int j;
for( j=PICK_UP_RAW_FIRST ; j<=PICK_UP_RAW_LAST ; j++ )
{
if( tradeStop->pick_up_array[j] )
hasPickUp = 1;
}
for( j=PICK_UP_PRODUCT_FIRST ; j<=PICK_UP_PRODUCT_LAST ; j++ )
{
if( tradeStop->pick_up_array[j] )
hasPickUp = 1;
}
//---- then delete the stop -----//
if( !hasPickUp )
{
del_stop(i, COMMAND_AI);
return 1;
}
}
//----------------------------------------------//
int nationRecno = firmMarket->nation_recno;
if( nationPtr->get_relation_status(nationRecno) == NATION_HOSTILE )
{
del_stop(i, COMMAND_AI);
return 1;
}
}
//----------- debug code ----------//
#ifdef DEBUG
for( i=stop_defined_num ; i>0 ; i-- )
{
err_when( firm_array.is_deleted(stop_array[i-1].firm_recno) );
}
#endif
return 0;
}
//------- End of function UnitCaravan::think_del_stop --------//
//------- Begin of function UnitCaravan::think_set_pick_up_type --------//
//
// Think about setting the pick up types of this caravan's stops.
//
void UnitCaravan::think_set_pick_up_type()
{
if( !is_visible() ) // cannot change pickup type if the caravan is inside a market place.
return;
if( stop_defined_num < 2 )
return;
//------------------------------------------//
err_when( firm_array.is_deleted(stop_array[0].firm_recno) );
err_when( firm_array.is_deleted(stop_array[1].firm_recno) );
Firm* firmPtr1 = firm_array[stop_array[0].firm_recno];
Firm* firmPtr2 = firm_array[stop_array[1].firm_recno];
if( firmPtr1->firm_id != FIRM_MARKET || // only when both firms are markets
firmPtr2->firm_id != FIRM_MARKET )
{
return;
}
if( firmPtr2->nation_recno == nation_recno && // only when the market is our own, we can use it as a TO market
((FirmMarket*)firmPtr2)->is_retail_market )
{
think_set_pick_up_type2( 1, 2 );
}
if( firmPtr1->nation_recno == nation_recno &&
((FirmMarket*)firmPtr1)->is_retail_market )
{
think_set_pick_up_type2( 2, 1 );
}
}
//------- End of function UnitCaravan::think_set_pick_up_type --------//
//------- Begin of function UnitCaravan::think_set_pick_up_type2 --------//
//
// Think about importing products from one firm to another
//
void UnitCaravan::think_set_pick_up_type2(int fromStopId, int toStopId)
{
FirmMarket* fromMarket = (FirmMarket*) firm_array[stop_array[fromStopId-1].firm_recno];
FirmMarket* toMarket = (FirmMarket*) firm_array[stop_array[toStopId-1].firm_recno];
//----- AI only knows about market to market trade -----//
if( fromMarket->firm_id != FIRM_MARKET || toMarket->firm_id != FIRM_MARKET )
return;
//---- think about adding new pick up types -----//
MarketGoods* marketGoods = fromMarket->market_goods_array;
TradeStop* tradeStop = stop_array+fromStopId-1;
int i;
for( i=0 ; iproduct_raw_id )
continue;
//----- only if this market has direct supplies -----//
if( marketGoods->supply_30days()==0 )
continue;
//-- when the from market has the product and the to market does not have the product, then trade this good --//
int pickUpType = PICK_UP_PRODUCT_FIRST+marketGoods->product_raw_id-1;
//------ toggle it if the current flag and the flag we need are different ----//
if( !tradeStop->pick_up_array[pickUpType-1] )
set_stop_pick_up(fromStopId, pickUpType, COMMAND_AI);
}
//---- think about droping existing pick up types -----//
for( i=PICK_UP_RAW_FIRST ; i<=PICK_UP_RAW_LAST ; i++ )
{
if( !tradeStop->pick_up_array[i-1] )
continue;
marketGoods = fromMarket->market_raw_array[i-PICK_UP_RAW_FIRST];
//----- if there is no supply, drop the pick up type -----//
if( !marketGoods || marketGoods->supply_30days() == 0 )
set_stop_pick_up(fromStopId, i, COMMAND_AI);
}
for( i=PICK_UP_PRODUCT_FIRST ; i<=PICK_UP_PRODUCT_LAST ; i++ )
{
if( !tradeStop->pick_up_array[i-1] )
continue;
marketGoods = fromMarket->market_product_array[i-PICK_UP_PRODUCT_FIRST];
//--- if the supply is not enough, drop the pick up type ---//
if( !marketGoods || marketGoods->supply_30days()==0 )
set_stop_pick_up(fromStopId, i, COMMAND_AI);
}
}
//------- End of function UnitCaravan::think_set_pick_up_type2 --------//