/*
* 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_CARA3.CPP
//Description : Unit Caravan unload/load functions
#include
#include
#include
#include
#include
#include
static char processed_raw_qty_array[MAX_RAW]; // 1 for not unload but can up load, 2 for unload but not up load
static char processed_product_raw_qty_array[MAX_PRODUCT]; // ditto
//--------- Begin of function UnitCaravan::market_unload_goods ---------//
//
void UnitCaravan::market_unload_goods()
{
FirmMarket *curMarket = (FirmMarket*) firm_array[stop_array[dest_stop_id-1].firm_recno];
err_when(curMarket->firm_id != FIRM_MARKET);
memset(processed_raw_qty_array, 0, sizeof(char)*MAX_RAW);
memset(processed_product_raw_qty_array, 0, sizeof(char)*MAX_PRODUCT);
//--------------------------------------------------------------------//
// only unload goods to our market
//--------------------------------------------------------------------//
if(curMarket->nation_recno!=nation_recno)
return;
//--------------------------------------------------------------------//
// unload goods
//-------------------------------------------------//
MarketGoods *marketGoods = curMarket->market_goods_array;
short unloadQty;
int goodsId, withEmptySlot=0;
int i;
for(i=0; iraw_id)
{
err_when(marketGoods->product_raw_id);
//-------------- is raw material ----------------//
goodsId = marketGoods->raw_id-1;
//if( (marketGoods->supply_30days()==0 && marketGoods->stock_qtymax_stock_qty) || // no supply and stock isn't full
// (marketGoods->stock_qtymonth_demand > marketGoods->supply_30days()) ) // demand > supply
// //##### end trevor 16/7 #######//
if(marketGoods->stock_qtymax_stock_qty)
{
//-------- demand > supply and stock is not full ----------//
if(raw_qty_array[goodsId]) // have this goods
{
//---------- process unload -------------//
unloadQty = (short) min(raw_qty_array[goodsId], curMarket->max_stock_qty-marketGoods->stock_qty);
raw_qty_array[goodsId] -= unloadQty;
err_when(raw_qty_array[goodsId]<0);
marketGoods->stock_qty += unloadQty;
processed_raw_qty_array[goodsId] += 2;
}
else if(!marketGoods->stock_qty && !marketGoods->supply_30days())
{
//---------- no supply, no stock, without this goods ------------//
withEmptySlot++;
//processed_raw_qty_array[goodsId] = 0; // reset to zero for handling empty slot
}
}
else if(raw_qty_array[goodsId]) // have this goods
{
processed_raw_qty_array[goodsId]++;
}
}
else if(marketGoods->product_raw_id)
{
err_when(marketGoods->raw_id);
//---------------- is product -------------------//
goodsId = marketGoods->product_raw_id-1;
//if( (marketGoods->supply_30days()==0 && marketGoods->stock_qtymax_stock_qty) || // no supply and stock isn't full
// //##### begin trevor 16/7 #######//
// (marketGoods->stock_qty<50 && marketGoods->month_demand > marketGoods->supply_30days()) ) // demand > supply
// //##### end trevor 16/7 #######//
if(marketGoods->stock_qtymax_stock_qty)
{
if(product_raw_qty_array[goodsId]) // have this goods
{
unloadQty = (short) min(product_raw_qty_array[goodsId], curMarket->max_stock_qty-marketGoods->stock_qty);
product_raw_qty_array[goodsId] -= unloadQty;
err_when(product_raw_qty_array[goodsId]<0);
marketGoods->stock_qty += unloadQty;
processed_product_raw_qty_array[goodsId] += 2;
}
else if(!marketGoods->stock_qty && !marketGoods->supply_30days()) // no supply, no stock, without this goods
{
withEmptySlot++;
//processed_product_raw_qty_array[goodsId] = 0; // reset to zero for handling empty slot
}
}
else if(product_raw_qty_array[goodsId]) // have this goods
{
processed_product_raw_qty_array[goodsId]++;
}
}
else // is empty
{
if(!market_unload_goods_in_empty_slot(curMarket, i))
break; // no goods for further checking
}
}
//-------------------------------------------------//
// unload new goods in the empty slots
//-------------------------------------------------//
if(withEmptySlot)
{
marketGoods = curMarket->market_goods_array;
for(i=0; istock_qty || marketGoods->supply_30days())
continue;
market_unload_goods_in_empty_slot(curMarket, i);
withEmptySlot--;
}
}
err_when(withEmptySlot);
}
//----------- End of function UnitCaravan::market_unload_goods -----------//
//--------- Begin of function UnitCaravan::market_unload_goods_in_empty_slot ---------//
// return 0 if no goods for further checking
// return 1 if unload goods successfully
//
int UnitCaravan::market_unload_goods_in_empty_slot(FirmMarket *curMarket, int position)
{
MarketGoods* marketGoods = curMarket->market_goods_array + position;
MarketGoods *checkGoods;
int productExistInOtherSlot, rawExistInOtherSlot;
//-------------------------------------------------//
// unload product and then raw
//-------------------------------------------------//
int processed, j;
for(processed=0, j=0; jmarket_goods_array;
productExistInOtherSlot = 0;
for(int k=0; kproduct_raw_id==j+1)
{
productExistInOtherSlot++;
break;
}
}
if(productExistInOtherSlot)
continue;
#ifdef DEBUG
MarketGoods *debugGoods = curMarket->market_goods_array;
for(int debugCount=0; debugCountproduct_raw_id==j+1);
#endif
//-**************************************************-//
//err_when(marketGoods->stock_qty);
marketGoods->stock_qty = (float) 0; // BUGHERE, there is a case that marketGoods->stock_qty > 0
//-**************************************************-//
processed_product_raw_qty_array[j] += 2;
curMarket->set_goods(0, j+1, position);
short unloadQty = (short) min(product_raw_qty_array[j], curMarket->max_stock_qty-marketGoods->stock_qty);
product_raw_qty_array[j] -= unloadQty;
marketGoods->stock_qty += unloadQty;
processed++;
break;
}
if(!processed)
{
for(j=0; jmarket_goods_array;
rawExistInOtherSlot = 0;
for(int k=0; kraw_id==j+1)
{
rawExistInOtherSlot++;
break;
}
}
if(rawExistInOtherSlot)
continue;
#ifdef DEBUG
MarketGoods *debugGoods = curMarket->market_goods_array;
for(int debugCount=0; debugCountraw_id==j+1);
#endif
//-**************************************************-//
//err_when(marketGoods->stock_qty);
marketGoods->stock_qty = (float) 0; // BUGHERE, there is a case that marketGoods->stock_qty > 0
//-**************************************************-//
processed_raw_qty_array[j] += 2;
curMarket->set_goods(1, j+1, position);
short unloadQty = (short) min(raw_qty_array[j], curMarket->max_stock_qty-marketGoods->stock_qty);
raw_qty_array[j] -= unloadQty;
marketGoods->stock_qty += unloadQty;
processed++;
break;
}
if(!processed && !productExistInOtherSlot && !rawExistInOtherSlot)
return 0; // no goods for further processsing
}
if( unit_array.selected_recno == sprite_recno )
info.disp();
return 1;
}
//----------- End of function UnitCaravan::market_unload_goods_in_empty_slot -----------//
//--------- Begin of function UnitCaravan::market_load_goods ---------//
//
void UnitCaravan::market_load_goods()
{
CaravanStop *stopPtr = stop_array+dest_stop_id-1;
err_when(stopPtr->pick_up_type == NO_PICK_UP);
FirmMarket *curMarket = (FirmMarket*) firm_array[ stopPtr->firm_recno ];
err_when(curMarket->firm_id != FIRM_MARKET);
MarketGoods *marketGoods=curMarket->market_goods_array;
//------------------------------------------------------------//
// scan the market, see if it has the specified pickup goods
//------------------------------------------------------------//
for(int i=0; iraw_id)
{
if(stopPtr->pick_up_array[marketGoods->raw_id-1])
market_load_goods_now(marketGoods, marketGoods->stock_qty);
}
else if(marketGoods->product_raw_id)
{
if(stopPtr->pick_up_array[marketGoods->product_raw_id-1+MAX_RAW])
market_load_goods_now(marketGoods, marketGoods->stock_qty);
}
}
}
//----------- End of function UnitCaravan::market_load_goods -----------//
//--------- Begin of function UnitCaravan::market_auto_load_goods ---------//
//
void UnitCaravan::market_auto_load_goods()
{
FirmMarket *curMarket = (FirmMarket*) firm_array[ stop_array[dest_stop_id-1].firm_recno ];
err_when(curMarket->firm_id != FIRM_MARKET);
MarketGoods *marketGoods = curMarket->market_goods_array;
//int isOurMarket = (curMarket->nation_recno==nation_recno); // is 1 or 0
int goodsId;
short loadQty;
//----------------------------------------------------------------------//
// keep empty stock if the market(AI) is for sale, otherwise use the
// default value
//----------------------------------------------------------------------//
//short minFirmStockQty = (int)curMarket->max_stock_qty/5; // keep at least 20% capacity in the firm if the market is not for sale
for(int i=0; istock_qty)
continue;
if(marketGoods->raw_id)
{
err_when(marketGoods->product_raw_id);
(goodsId = marketGoods->raw_id)--;
if(processed_raw_qty_array[goodsId]==2)
continue; // continue if it is the goods unloaded
if(marketGoods->stock_qty > MIN_FIRM_STOCK_QTY)
{
loadQty = (short) (marketGoods->stock_qty - MIN_FIRM_STOCK_QTY);
err_when(loadQty<0);
market_load_goods_now(marketGoods, (float) loadQty);
}
}
//else if(marketGoods->product_raw_id && isOurMarket) // only load product in our market
else if(marketGoods->product_raw_id)
{
err_when(marketGoods->raw_id);
(goodsId = marketGoods->product_raw_id)--;
if(processed_product_raw_qty_array[goodsId]==2)
continue; // continue if it is the goods unloaded
if(marketGoods->stock_qty > MIN_FIRM_STOCK_QTY)
{
loadQty = (short) (marketGoods->stock_qty - MIN_FIRM_STOCK_QTY);
err_when(loadQty<0);
market_load_goods_now(marketGoods, (float) loadQty);
}
}
}
}
//----------- End of function UnitCaravan::market_auto_load_goods -----------//
//--------- Begin of function UnitCaravan::market_load_goods_now ---------//
//
void UnitCaravan::market_load_goods_now(MarketGoods* marketGoods, float loadQty)
{
Nation *nationPtr = nation_array[nation_recno];
int marketNationRecno = firm_array[stop_array[dest_stop_id-1].firm_recno]->nation_recno;
short qty;
int goodsId;
if(marketGoods->product_raw_id)
{
//---------------- is product ------------------//
err_when(marketGoods->raw_id);
(goodsId = marketGoods->product_raw_id)--;
qty = min(MAX_CARAVAN_CARRY_QTY-product_raw_qty_array[goodsId], (int)loadQty);
if(marketNationRecno!=nation_recno) // calculate the qty again if this is not our own market
{
qty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/PRODUCT_PRICE, qty) : 0;
if(qty)
nationPtr->import_goods(IMPORT_PRODUCT, marketNationRecno, (float)qty * PRODUCT_PRICE);
}
product_raw_qty_array[goodsId] += qty;
err_when(product_raw_qty_array[goodsId]<0 || product_raw_qty_array[goodsId]>MAX_CARAVAN_CARRY_QTY);
marketGoods->stock_qty -= qty;
}
else if(marketGoods->raw_id)
{
//---------------- is raw ---------------------//
err_when(marketGoods->product_raw_id);
(goodsId = marketGoods->raw_id)--;
qty = min(MAX_CARAVAN_CARRY_QTY-raw_qty_array[goodsId], (int)loadQty);
if(marketNationRecno!=nation_recno) // calculate the qty again if this is not our own market
{
qty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/RAW_PRICE, qty) : 0;
if(qty)
nationPtr->import_goods(IMPORT_RAW, marketNationRecno, (float)qty * RAW_PRICE);
}
raw_qty_array[goodsId] += qty;
err_when(raw_qty_array[goodsId]<0 || raw_qty_array[goodsId]>MAX_CARAVAN_CARRY_QTY);
marketGoods->stock_qty -= qty;
}
//### begin trevor 7/8 ###//
if( qty > 0 )
last_load_goods_date = info.game_date;
//#### end trevor 7/8 ####//
}
//----------- End of function UnitCaravan::market_load_goods_now -----------//
//--------- Begin of function UnitCaravan::mine_load_goods ---------//
void UnitCaravan::mine_load_goods(char pickUpType)
{
if(pickUpType == NO_PICK_UP)
return; // return if not allowed to load any goods
err_when(pickUpType>=PICK_UP_PRODUCT_FIRST && pickUpType<=PICK_UP_PRODUCT_LAST);
CaravanStop *stopPtr = stop_array+dest_stop_id-1;
FirmMine *curMine = (FirmMine*) firm_array[stopPtr->firm_recno];
err_when(curMine->firm_id != FIRM_MINE);
if(curMine->nation_recno!=nation_recno)
return; // no action if this is not our own mine
//------------- load goods -----------//
int searchRawId = pickUpType-PICK_UP_RAW_FIRST+1;
if(pickUpType==AUTO_PICK_UP || curMine->raw_id==searchRawId) // auto_pick_up or is the raw to pick up
{
int goodsId = curMine->raw_id-1;
short maxLoadQty = (pickUpType!=AUTO_PICK_UP) ? (short)curMine->stock_qty :
max(0, (int)(curMine->stock_qty-MIN_FIRM_STOCK_QTY)); // max Qty mine can supply
short qty = min(MAX_CARAVAN_CARRY_QTY-raw_qty_array[goodsId], maxLoadQty); // max Qty caravan can carry
raw_qty_array[goodsId] += qty;
err_when(raw_qty_array[goodsId]<0 || raw_qty_array[goodsId]>MAX_CARAVAN_CARRY_QTY);
curMine->stock_qty -= qty;
//### begin trevor 7/8 ####//
if( maxLoadQty > 0 )
last_load_goods_date = info.game_date;
//#### end trevor 7/8 ####//
}
}
//----------- End of function UnitCaravan::mine_load_goods -----------//
//--------- Begin of function UnitCaravan::factory_unload_goods ---------//
// unload raw material to factory
//
void UnitCaravan::factory_unload_goods()
{
CaravanStop *stopPtr = stop_array+dest_stop_id-1;
FirmFactory *curFactory = (FirmFactory*) firm_array[stopPtr->firm_recno];
err_when(curFactory->firm_id != FIRM_FACTORY);
if(curFactory->nation_recno!=nation_recno)
return; // don't unload goods if this isn't our own factory
//--- if the factory does not have any stock and there is no production, set it to type of raw materials the caravan is carring ---//
if( curFactory->stock_qty == 0 &&
curFactory->raw_stock_qty == 0 &&
curFactory->production_30days() == 0 )
{
int rawCount=0;
int rawId=0;
for( int i=0 ; i 0 )
{
rawCount++;
rawId=i+1;
}
}
//-- only if the caravan only carries one type of raw material --//
if( rawCount==1 && rawId )
curFactory->product_raw_id = rawId;
}
//---------- unload materials automatically --------//
int goodsId = curFactory->product_raw_id-1;
if(raw_qty_array[goodsId]) // caravan has this raw materials
{
short qty = min(raw_qty_array[goodsId], (short)(curFactory->max_raw_stock_qty-curFactory->raw_stock_qty));
raw_qty_array[goodsId] -= qty;
err_when(raw_qty_array[goodsId]<0);
curFactory->raw_stock_qty += qty;
err_when(curFactory->raw_stock_qty>curFactory->max_raw_stock_qty);
}
}
//----------- End of function UnitCaravan::factory_unload_goods -----------//
//--------- Begin of function UnitCaravan::factory_load_goods ---------//
void UnitCaravan::factory_load_goods(char pickUpType)
{
if(pickUpType==NO_PICK_UP)
return; // return not allowed to load any goods
err_when(pickUpType>=PICK_UP_RAW_FIRST && pickUpType<=PICK_UP_RAW_LAST);
CaravanStop *stopPtr = stop_array+dest_stop_id-1;
FirmFactory *curFactory = (FirmFactory*) firm_array[stopPtr->firm_recno];
err_when(curFactory->firm_id != FIRM_FACTORY);
if(curFactory->nation_recno!=nation_recno)
return; // don't load goods if this isn't our own factory
//------------- load goods -----------//
int searchProductRawId = pickUpType-PICK_UP_PRODUCT_FIRST+1;
if(pickUpType==AUTO_PICK_UP || curFactory->product_raw_id==searchProductRawId) // auto_pick_up or is the product to pick up
{
int goodsId = curFactory->product_raw_id-1;
short maxLoadQty = (pickUpType!=AUTO_PICK_UP) ? (short)curFactory->stock_qty :
max(0, (int)(curFactory->stock_qty-MIN_FIRM_STOCK_QTY)); // max Qty factory can supply
short qty = min(MAX_CARAVAN_CARRY_QTY-product_raw_qty_array[goodsId], maxLoadQty); // max Qty caravan can carry
product_raw_qty_array[goodsId] += qty;
err_when(product_raw_qty_array[goodsId]<0 || product_raw_qty_array[goodsId]>MAX_CARAVAN_CARRY_QTY);
curFactory->stock_qty -= qty;
//### begin trevor 7/8 ####//
if( maxLoadQty > 0 )
last_load_goods_date = info.game_date;
//#### end trevor 7/8 ####//
}
}
//----------- End of function UnitCaravan::factory_load_goods -----------//