1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405 |
- /*
- * 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 <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OU_MARI3.CPP
- //Description: UnitMarine - functions for loading/unloading goods, trading
- #include <ALL.h>
- #include <OREMOTE.h>
- #include <OU_CARA.h>
- #include <OU_MARI.h>
- #include <OF_HARB.h>
- #include <ONATION.h>
- #include <OF_FACT.h>
- #include <OF_MINE.h>
- #include <OCONFIG.h>
- static char mprocessed_raw_qty_array[MAX_LINKED_FIRM_FIRM][MAX_RAW]; // 1 for not unload but can up load, 2 for unload but not up load
- static char mprocessed_product_raw_qty_array[MAX_LINKED_FIRM_FIRM][MAX_PRODUCT]; // ditto
- static char linked_mine_num;
- static char linked_factory_num;
- static char linked_market_num;
- static short linked_mine_array[MAX_LINKED_FIRM_FIRM];
- static short linked_factory_array[MAX_LINKED_FIRM_FIRM];
- static short linked_market_array[MAX_LINKED_FIRM_FIRM];
- static char empty_slot_position_array[MAX_LINKED_FIRM_FIRM];
- static char firm_selected_array[MAX_LINKED_FIRM_FIRM];
- //--------- Begin of function UnitMarine::del_stop ---------//
- void UnitMarine::del_stop(int stopId, char remoteAction)
- {
- // ####### begin Gilbert 30/7 #######//
- if(!remoteAction && remote.is_enable())
- {
- // packet structure : <unit recno> <stop id>
- short *shortPtr = (short *) remote.new_send_queue_msg(MSG_U_SHIP_DEL_STOP, 2*sizeof(short));
- *shortPtr = sprite_recno;
- shortPtr[1] = stopId;
- return;
- }
- // ####### end Gilbert 30/7 #######//
- if(remote.is_enable() && stop_array[stopId-1].firm_recno==0)
- return;
- stop_array[stopId-1].firm_recno = 0;
- stop_defined_num--;
- update_stop_list();
- if(unit_array.selected_recno==sprite_recno)
- {
- if(!remote.is_enable() || nation_recno==nation_array.player_recno || config.show_ai_info)
- info.disp();
- }
- }
- //---------- End of function UnitMarine::del_stop ----------//
- //--------- Begin of function UnitMarine::update_stop_list ---------//
- void UnitMarine::update_stop_list()
- {
- //------------- used to debug for multiplayer game ------------------//
- #ifdef DEBUG
- m.random(100);
- #endif
- //-------------------------------------------------------//
- // backup original destination stop firm recno
- //-------------------------------------------------------//
- err_when(stop_defined_num<0 || stop_defined_num>MAX_STOP_FOR_SHIP);
- short nextStopRecno = dest_stop_id ? stop_array[dest_stop_id-1].firm_recno : 0;
- //----------------------------------------------------------------------//
- // check stop existence and the relationship between firm's nation
- //----------------------------------------------------------------------//
- ShipStop *nodePtr = stop_array;
- Firm *firmPtr;
- int i;
- for(i=0; i<MAX_STOP_FOR_SHIP; i++, nodePtr++)
- {
- if(!nodePtr->firm_recno)
- continue;
- if(firm_array.is_deleted(nodePtr->firm_recno))
- {
- nodePtr->firm_recno = 0; // clear the recno
- stop_defined_num--;
- continue;
- }
- firmPtr = firm_array[nodePtr->firm_recno];
- if( !can_set_stop(firmPtr->firm_recno) ||
- firmPtr->loc_x1 != nodePtr->firm_loc_x1 ||
- firmPtr->loc_y1 != nodePtr->firm_loc_y1 )
- {
- nodePtr->firm_recno = 0;
- stop_defined_num--;
- continue;
- }
- }
- //-------------------------------------------------------//
- // remove duplicate node
- //-------------------------------------------------------//
- ShipStop *insertNodePtr = stop_array;
- if(stop_defined_num<1)
- {
- memset(stop_array, 0, sizeof(ShipStop)*MAX_STOP_FOR_SHIP);
- dest_stop_id = 0;
- return; // no stop
- }
- //-------------------------------------------------------//
- // move the only firm_recno to the beginning of the array
- //-------------------------------------------------------//
- short compareRecno;
- for(i=0, nodePtr=stop_array; i<MAX_STOP_FOR_SHIP; i++, nodePtr++)
- {
- if(nodePtr->firm_recno)
- {
- compareRecno = nodePtr->firm_recno;
- break;
- }
- }
- if(i++) // else, the first record is already in the beginning of the array
- memcpy(insertNodePtr, nodePtr, sizeof(ShipStop));
- if(stop_defined_num==1)
- {
- memset(insertNodePtr+1, 0, sizeof(ShipStop)*(MAX_STOP_FOR_SHIP-1));
- dest_stop_id = 1;
- return;
- }
- short unprocessed = stop_defined_num-1;
- err_when(i==MAX_STOP_FOR_SHIP); // error if only one record
- err_when(!unprocessed);
- insertNodePtr++;
- nodePtr++;
- for(; i<MAX_STOP_FOR_SHIP && unprocessed; i++, nodePtr++)
- {
- if(!nodePtr->firm_recno)
- continue; // empty
- err_when(!nodePtr->firm_recno);
- if(nodePtr->firm_recno==compareRecno)
- {
- nodePtr->firm_recno = 0;
- stop_defined_num--;
- }
- else
- {
- compareRecno = nodePtr->firm_recno;
- if(insertNodePtr!=nodePtr)
- memcpy(insertNodePtr++, nodePtr, sizeof(ShipStop));
- else
- insertNodePtr++;
- }
- unprocessed--;
- }
- if(stop_defined_num>2)
- {
- //-------- compare the first and the end record -------//
- nodePtr = stop_array + stop_defined_num - 1; // point to the end
- if(nodePtr->firm_recno == stop_array[0].firm_recno)
- {
- nodePtr->firm_recno = 0; // remove the end record
- stop_defined_num--;
- }
- }
- if(stop_defined_num<MAX_STOP_FOR_SHIP)
- memset(stop_array+stop_defined_num, 0, sizeof(ShipStop)*(MAX_STOP_FOR_SHIP-stop_defined_num));
- #ifdef DEBUG
- int debugCount;
- for(debugCount=0; debugCount<stop_defined_num; debugCount++)
- err_when(!stop_array[debugCount].firm_recno);
- for(; debugCount<MAX_STOP_FOR_SHIP; debugCount++)
- err_when(stop_array[debugCount].firm_recno);
- for(debugCount=0; debugCount<stop_defined_num; debugCount++)
- err_when(stop_array[debugCount].firm_recno &&
- stop_array[debugCount].firm_recno==stop_array[(debugCount+1)%MAX_STOP_FOR_SHIP].firm_recno);
- #endif
- //-----------------------------------------------------------------------------------------//
- // There should be at least one stop in the list. Otherwise, clear all the stops
- //-----------------------------------------------------------------------------------------//
- int ourFirmExist = 0;
- for(i=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
- {
- err_when(firm_array.is_deleted(nodePtr->firm_recno));
- firmPtr = firm_array[nodePtr->firm_recno];
- if(firmPtr->nation_recno==nation_recno)
- {
- ourFirmExist++;
- break;
- }
- }
- if(!ourFirmExist) // none of the markets belong to our nation
- {
- memset(stop_array, 0, MAX_STOP_FOR_SHIP * sizeof(ShipStop));
- journey_status = ON_WAY_TO_FIRM;
- dest_stop_id = 0;
- stop_defined_num = 0;
- return;
- }
- //-----------------------------------------------------------------------------------------//
- // reset dest_stop_id since the order of the stop may be changed
- //-----------------------------------------------------------------------------------------//
- int xLoc = next_x_loc();
- int yLoc = next_y_loc();
- int dist, minDist=0x7FFF;
- for(i=0, dest_stop_id=0, nodePtr=stop_array; i<stop_defined_num; i++, nodePtr++)
- {
- if(nodePtr->firm_recno==nextStopRecno)
- {
- dest_stop_id = i+1;
- break;
- }
- else
- {
- firmPtr = firm_array[nodePtr->firm_recno];
- dist = m.points_distance(xLoc, yLoc, firmPtr->center_x, firmPtr->center_y);
- if(dist<minDist)
- {
- dist = minDist;
- dest_stop_id = i+1;
- }
- }
- }
- err_when(dest_stop_id<0 || dest_stop_id>MAX_STOP_FOR_SHIP);
- }
- //----------- End of function UnitMarine::update_stop_list -----------//
- //--------- Begin of function UnitMarine::get_next_stop_id ---------//
- // Get the id. of the next defined stop.
- //
- // [int] curStopId - the id. of the current stop.
- // if it is MAX_STOP_FOR_SHIP, this function will return
- // the id. of the first valid stop.
- //
- // (default: MAX_STOP_FOR_SHIP)
- // return : 0 ~ MAX_STOP_FOR_SHIP, where 0 for no valid stop
- //
- int UnitMarine::get_next_stop_id(int curStopId)
- {
- int nextStopId = (curStopId>=stop_defined_num) ? 1 : curStopId+1;
- ShipStop *stopPtr = stop_array+nextStopId-1;
- int needUpdate = 0;
- if(firm_array.is_deleted(stopPtr->firm_recno))
- needUpdate++;
- else
- {
- Firm *firmPtr = firm_array[stopPtr->firm_recno];
- if( !can_set_stop(firmPtr->firm_recno) ||
- firmPtr->loc_x1 != stopPtr->firm_loc_x1 ||
- firmPtr->loc_y1 != stopPtr->firm_loc_y1 )
- {
- needUpdate++;
- }
- }
- if(needUpdate)
- {
- short preStopRecno = stop_array[curStopId-1].firm_recno;
- update_stop_list();
- if(!stop_defined_num)
- return 0; // no stop is valid
- int i;
- for(i=1, stopPtr=stop_array; i<=stop_defined_num; i++, stopPtr++)
- {
- if(stopPtr->firm_recno==preStopRecno)
- nextStopId = (i>=stop_defined_num) ? 1 : i+1;
- }
- }
- return nextStopId;
- }
- //----------- End of function UnitMarine::get_next_stop_id -----------//
- //--------- Begin of function UnitMarine::can_set_stop ---------//
- //
- // Whether can set a caravan's stop on the given firm.
- //
- int UnitMarine::can_set_stop(int firmRecno)
- {
- Firm* firmPtr = firm_array[firmRecno];
- if( firmPtr->under_construction )
- return 0;
- if( firmPtr->firm_id != FIRM_HARBOR )
- return 0;
- return nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty;
- }
- //----------- End of function UnitMarine::can_set_stop -----------//
- //--------- Begin of function UnitMarine::pre_process ---------//
- void UnitMarine::pre_process()
- {
- #define SURROUND_FIRM_WAIT_FACTOR 10
- Unit::pre_process();
- if(hit_points<=0 || action_mode==ACTION_DIE || cur_action==SPRITE_DIE)
- return;
- err_when(action_mode==ACTION_DIE || cur_action==SPRITE_DIE || hit_points<=0);
- if(action_mode2>=ACTION_ATTACK_UNIT && action_mode2<=ACTION_ATTACK_WALL)
- return; // don't process trading if unit is attacking
- if(auto_mode) // process trading automatically, same as caravan
- {
- if(!stop_defined_num)
- return;
- //----------------- if there is only one defined stop --------------------//
- if(stop_defined_num==1)
- {
- if( firm_array.is_deleted(stop_array[0].firm_recno) )
- {
- update_stop_list();
- return;
- }
- Firm *firmPtr = firm_array[stop_array[0].firm_recno];
- if(firmPtr->loc_x1!=stop_array[0].firm_loc_x1 || firmPtr->loc_y1!=stop_array[0].firm_loc_y1)
- {
- update_stop_list();
- return;
- }
- int curXLoc = next_x_loc();
- int curYLoc = next_y_loc();
- int moveStep = move_step_magn();
- if(curXLoc<firmPtr->loc_x1-moveStep || curXLoc>firmPtr->loc_x2+moveStep ||
- curYLoc<firmPtr->loc_y1-moveStep || curYLoc>firmPtr->loc_y2+moveStep)
- {
- //### begin alex 6/10 ###//
- /*if((move_to_x_loc>=firmPtr->loc_x1-moveStep || move_to_x_loc<=firmPtr->loc_x2+moveStep) &&
- (move_to_y_loc>=firmPtr->loc_y1-moveStep || move_to_y_loc<=firmPtr->loc_y2+moveStep))
- return;
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
- journey_status = ON_WAY_TO_FIRM;*/
- if(cur_action==SPRITE_IDLE)
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
- else
- journey_status = ON_WAY_TO_FIRM;
- //#### end alex 6/10 ####//
- }
- else
- {
- if(cur_x==next_x && cur_y==next_y && cur_action==SPRITE_IDLE)
- {
- journey_status = SURROUND_FIRM;
- if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
- {
- if(wait_count<=0)
- {
- //---------- unloading goods -------------//
- cur_firm_recno = stop_array[0].firm_recno;
- get_harbor_linked_firm_info();
- harbor_unload_goods();
- wait_count = MAX_SHIP_WAIT_TERM*SURROUND_FIRM_WAIT_FACTOR;
- cur_firm_recno = 0;
- }
- else
- wait_count--;
- }
- }
- }
- return;
- }
- //------------ if there are more than one defined stop ---------------//
- err_when(stop_defined_num<=1);
- if(journey_status==INSIDE_FIRM)
- ship_in_firm();
- else
- ship_on_way();
- }
- else if(journey_status==INSIDE_FIRM)
- ship_in_firm(0); // autoMode is off
- }
- //---------- End of function UnitMarine::pre_process ----------//
- //--------- Begin of function UnitMarine::ship_in_firm ---------//
- // journey_status : INSIDE_FIRM --> ON_WAY_TO_FIRM
- // NO_STOP_DEFINED if no valid stop
- // SURROUND_FIRM if only one stop
- //
- // <int> autoMode - 1 if autoMode is on
- // - 0 otherwise
- //
- void UnitMarine::ship_in_firm(int autoMode)
- {
- //-----------------------------------------------------------------------------//
- // the harbor is deleted while the ship is in harbor
- //-----------------------------------------------------------------------------//
- if(cur_firm_recno && firm_array.is_deleted(cur_firm_recno))
- {
- hit_points = (float) 0; // ship also die if the harbor is deleted
- unit_array.disappear_in_firm(sprite_recno); // ship also die if the harnor is deleted
- return;
- }
- //-----------------------------------------------------------------------------//
- // waiting (time to upload/download cargo)
- //-----------------------------------------------------------------------------//
- if(wait_count>0)
- {
- wait_count--;
- return;
- }
- //-----------------------------------------------------------------------------//
- // leave the harbor and go to another harbor if possible
- //-----------------------------------------------------------------------------//
- ShipStop *stopPtr = stop_array + dest_stop_id - 1;
- int xLoc = stop_x_loc;
- int yLoc = stop_y_loc;
- Location *locPtr = world.get_loc(xLoc, yLoc);
- Firm *firmPtr;
- if(xLoc%2==0 && yLoc%2==0 && locPtr->can_move(mobile_type))
- init_sprite(xLoc, yLoc); // appear in the location the unit disappeared before
- else
- {
- //---- the entering location is blocked, select another location to leave ----//
- err_when(cur_firm_recno==0);
- firmPtr = firm_array[cur_firm_recno];
- if(appear_in_firm_surround(xLoc, yLoc, firmPtr))
- {
- init_sprite(xLoc, yLoc);
- stop();
- }
- else
- {
- wait_count = MAX_SHIP_WAIT_TERM*10; //********* BUGHERE, continue to wait or ....
- return;
- }
- }
- //-------------- get next stop id. ----------------//
- int nextStopId = get_next_stop_id(dest_stop_id);
- if(!nextStopId || dest_stop_id==nextStopId)
- {
- dest_stop_id = nextStopId;
- journey_status = (!nextStopId) ? NO_STOP_DEFINED : SURROUND_FIRM;
- return; // no stop or only one stop is valid
- }
- dest_stop_id = nextStopId;
- firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
- cur_firm_recno = 0;
- journey_status = ON_WAY_TO_FIRM;
- if(autoMode) // move to next firm only if autoMode is on
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
- }
- //---------- End of function UnitMarine::ship_in_firm ----------//
- //--------- Begin of function UnitMarine::ship_on_way ---------//
- void UnitMarine::ship_on_way()
- {
- //### begin alex 6/10 ###//
- //FirmInfo *firmInfo = firm_res[FIRM_HARBOR];
- //#### end alex 6/10 ####//
- if(cur_action==SPRITE_IDLE && journey_status!=SURROUND_FIRM)
- {
- if(!firm_array.is_deleted(stop_array[dest_stop_id-1].firm_recno))
- {
- Firm *firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
- int nextXLoc = next_x_loc();
- int nextYLoc = next_y_loc();
- int moveStep = move_step_magn();
- if(nextXLoc>=firmPtr->loc_x1-moveStep && nextXLoc<=firmPtr->loc_x2+moveStep &&
- nextYLoc>=firmPtr->loc_y1-moveStep && nextYLoc<=firmPtr->loc_y2+moveStep)
- journey_status = SURROUND_FIRM;
- return;
- }
- }
- err_when(cur_action==SPRITE_ATTACK || action_mode==ACTION_ATTACK_UNIT || action_mode==ACTION_ATTACK_FIRM ||
- action_mode==ACTION_ATTACK_TOWN || action_mode==ACTION_ATTACK_WALL);
- if(unit_array.is_deleted(sprite_recno))
- return; //-***************** BUGHERE ***************//
- if(firm_array.is_deleted(stop_array[dest_stop_id-1].firm_recno))
- {
- update_stop_list();
- if(stop_defined_num) // move to next stop
- {
- Firm *firmPtr = firm_array[stop_array[dest_stop_id-1].firm_recno];
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, firmPtr->firm_id);
- }
- return;
- }
- ShipStop *stopPtr = stop_array + dest_stop_id - 1;
- Firm *firmPtr = firm_array[stopPtr->firm_recno];
- int nextXLoc = next_x_loc();
- int nextYLoc = next_y_loc();
- int moveStep = move_step_magn();
- if(journey_status==SURROUND_FIRM ||
- ( nextXLoc==move_to_x_loc && nextYLoc==move_to_y_loc && cur_x==next_x && cur_y==next_y && // move in a tile exactly
- (nextXLoc>=firmPtr->loc_x1-moveStep && nextXLoc<=firmPtr->loc_x2+moveStep &&
- nextYLoc>=firmPtr->loc_y1-moveStep && nextYLoc<=firmPtr->loc_y2+moveStep) ))
- {
- extra_move_in_beach = NO_EXTRA_MOVE; // since the ship may enter the firm in odd location
- stopPtr->update_pick_up();
- //-------------------------------------------------------//
- // load/unload goods
- //-------------------------------------------------------//
- cur_firm_recno = stopPtr->firm_recno;
- if(nation_array[nation_recno]->get_relation(firmPtr->nation_recno)->trade_treaty)
- {
- get_harbor_linked_firm_info();
- harbor_unload_goods();
- if(stopPtr->pick_up_type == AUTO_PICK_UP)
- harbor_auto_load_goods();
- else if(stopPtr->pick_up_type!=NO_PICK_UP)
- harbor_load_goods();
- }
- //-------------------------------------------------------//
- //-------------------------------------------------------//
- stop_x_loc = move_to_x_loc; // store entering location
- stop_y_loc = move_to_y_loc;
- wait_count = MAX_SHIP_WAIT_TERM; // set waiting term
- reset_path();
- deinit_sprite(1); // the ship enters the harbor now. 1-keep it selected if it is currently selected
- err_when(cur_x!=-1);
- cur_x--; // set cur_x to -2, such that invisible but still process pre_process()
- journey_status = INSIDE_FIRM;
- }
- else
- {
- if(cur_action!=SPRITE_MOVE)
- {
- //----------------------------------------------------//
- // blocked by something, go to the destination again
- // note: if return value is 0, cannot reach the firm. //*********BUGHERE
- //----------------------------------------------------//
- move_to_firm_surround(firmPtr->loc_x1, firmPtr->loc_y1, sprite_info->loc_width, sprite_info->loc_height, FIRM_HARBOR);
- journey_status = ON_WAY_TO_FIRM;
- }
- }
- }
- //---------- End of function UnitMarine::ship_on_way ----------//
- //--------- Begin of function UnitMarine::appear_in_firm_surround ---------//
- int UnitMarine::appear_in_firm_surround(int& xLoc, int& yLoc, Firm* firmPtr)
- {
- FirmInfo *firmInfo = firm_res[FIRM_HARBOR];
- int firmWidth = firmInfo->loc_width;
- int firmHeight = firmInfo->loc_height;
- int smallestCount = firmWidth * firmHeight + 1;
- int largestCount = (firmWidth+2) * (firmHeight+2);
- int countLimit = largestCount - smallestCount;
- int count = m.random(countLimit)+smallestCount;
- int checkXLoc, checkYLoc, xOffset, yOffset, found=0;
- Location *locPtr;
- //-----------------------------------------------------------------//
- for(int i=0; i<countLimit; i++)
- {
- m.cal_move_around_a_point(count, firmWidth, firmHeight, xOffset, yOffset);
- checkXLoc = firmPtr->loc_x1 + xOffset;
- checkYLoc = firmPtr->loc_y1 + yOffset;
- if(checkXLoc%2 || checkYLoc%2||
- checkXLoc<0 || checkXLoc>=MAX_WORLD_X_LOC || checkYLoc<0 || checkYLoc>=MAX_WORLD_Y_LOC)
- {
- count++;
- continue;
- }
- locPtr = world.get_loc(checkXLoc, checkYLoc);
- if(locPtr->can_move(mobile_type))
- {
- found++;
- break;
- }
- count++;
- if(count > largestCount)
- count = smallestCount;
- }
- //-----------------------------------------------------------------//
- if(found)
- {
- xLoc = checkXLoc;
- yLoc = checkYLoc;
- return 1;
- }
- return 0;
- }
- //---------- End of function UnitMarine::appear_in_firm_surround ----------//
- //--------- Begin of function UnitMarine::get_harbor_linked_firm_info ---------//
- void UnitMarine::get_harbor_linked_firm_info()
- {
- FirmHarbor *firmHarborPtr = (FirmHarbor*) firm_array[cur_firm_recno];
- err_when(firmHarborPtr->firm_id!=FIRM_HARBOR);
- firmHarborPtr->update_linked_firm_info();
- linked_mine_num = firmHarborPtr->get_linked_mine_num();
- linked_factory_num = firmHarborPtr->get_linked_factory_num();
- linked_market_num = firmHarborPtr->get_linked_market_num();
- memcpy(linked_mine_array, firmHarborPtr->linked_mine_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
- memcpy(linked_factory_array, firmHarborPtr->linked_factory_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
- memcpy(linked_market_array, firmHarborPtr->linked_market_array, sizeof(short)*MAX_LINKED_FIRM_FIRM);
- }
- //---------- End of function UnitMarine::get_harbor_linked_firm_info ----------//
- //--------- Begin of function UnitMarine::harbor_unload_goods ---------//
- void UnitMarine::harbor_unload_goods()
- {
- if(!linked_mine_num && !linked_factory_num && !linked_market_num)
- return; // no linked firm requires or supplys raw and product
-
- for(int i=0; i<MAX_LINKED_FIRM_FIRM; i++)
- {
- memset(mprocessed_raw_qty_array[i], 0, sizeof(char)*MAX_RAW);
- memset(mprocessed_product_raw_qty_array[i], 0, sizeof(char)*MAX_PRODUCT);
- }
- harbor_unload_product();
- harbor_unload_raw();
- }
- //----------- End of function UnitMarine::harbor_unload_goods -----------//
- //--------- Begin of function UnitMarine::harbor_unload_product ---------//
- // Product --> market
- //
- void UnitMarine::harbor_unload_product()
- {
- if(!linked_market_num)
- return;
- err_when(linked_market_num>MAX_LINKED_FIRM_FIRM);
- int i, j, k;
- short totalDemand;
- short *marketNodePtr; // point to linked_market_array
- char *firmSelectedPtr; // mark which firm is used
- FirmMarket *marketPtr;
- MarketGoods *marketProductPtr;
- MarketGoods *marketGoodsPtr; // used to find empty slot
- short curStock, unloadQty, useEmptySlot;
- for(i=0; i<MAX_PRODUCT; i++)
- {
- if(!product_raw_qty_array[i])
- continue; // without this goods
- //----------------------------------------------------------------------//
- // calculate the demand of this goods in market
- //----------------------------------------------------------------------//
- totalDemand = 0;
- memset(empty_slot_position_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- marketNodePtr = linked_market_array;
- firmSelectedPtr = firm_selected_array;
- for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
- {
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- if(marketPtr->nation_recno!=nation_recno)
- continue; // don't unload goods to market of other nation
- if(marketPtr->ai_status==MARKET_FOR_SELL)
- continue; // clearing the market stock, so no unloading
- //---------- check the demand of this goods in the market ---------//
- marketProductPtr = marketPtr->market_product_array[i];
- if(marketProductPtr)
- {
- err_when(marketProductPtr->product_raw_id && marketProductPtr->raw_id);
- totalDemand += (short)(marketPtr->max_stock_qty - marketProductPtr->stock_qty);
- ++*firmSelectedPtr;
- }
- else // don't have this product, clear for empty slot
- {
- marketGoodsPtr = marketPtr->market_goods_array;
- for(k=0; k<MAX_MARKET_GOODS; k++, marketGoodsPtr++)
- {
- err_when(marketGoodsPtr->product_raw_id && marketGoodsPtr->raw_id);
- if(!marketGoodsPtr->stock_qty && !marketGoodsPtr->supply_30days())
- {
- empty_slot_position_array[j] = k;
- totalDemand += (short)marketPtr->max_stock_qty;
- ++*firmSelectedPtr;
- break;
- }
- }
- }
- }
- //----------------------------------------------------------------------//
- // distribute the stock into each market
- //----------------------------------------------------------------------//
- curStock = product_raw_qty_array[i];
- marketNodePtr = linked_market_array;
- firmSelectedPtr = firm_selected_array;
- for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- marketProductPtr = marketPtr->market_product_array[i];
- if(!marketProductPtr) // using empty slot, don't set the pointer to the market_goods_array until unloadQty>0
- {
- useEmptySlot = 1;
- marketProductPtr = marketPtr->market_goods_array + empty_slot_position_array[j];
- }
- else
- useEmptySlot = 0;
- unloadQty = totalDemand ? (short)((marketPtr->max_stock_qty-marketProductPtr->stock_qty)*curStock/totalDemand + 0.5) : 0;
- unloadQty = min((short)(marketPtr->max_stock_qty-marketProductPtr->stock_qty), unloadQty);
- unloadQty = min(product_raw_qty_array[i], unloadQty);
- if(unloadQty)
- {
- if(useEmptySlot)
- marketPtr->set_goods(0, i+1, empty_slot_position_array[j]);
- marketProductPtr->stock_qty += unloadQty;
- err_when(marketProductPtr->stock_qty > marketPtr->max_stock_qty);
- product_raw_qty_array[i] -= unloadQty;
- err_when(product_raw_qty_array[i] < 0);
- mprocessed_product_raw_qty_array[linked_mine_num+linked_factory_num+j][i] += 2;
- }
- }
- }
- }
- //----------- End of function UnitMarine::harbor_unload_product -----------//
- //--------- Begin of function UnitMarine::harbor_unload_raw ---------//
- // Raw material --> market and factory
- //
- void UnitMarine::harbor_unload_raw()
- {
- if(!linked_factory_num && !linked_market_num)
- return;
- err_when(linked_factory_num+linked_market_num > MAX_LINKED_FIRM_FIRM);
- int i, j, k;
- short totalDemand;
- short *factoryNodePtr; // point to linked_factory_array
- short *marketNodePtr; // point to linked_market_array
- char *firmSelectedPtr; // mark which firm is used (for factory and market)
- FirmFactory *factoryPtr;
- FirmMarket *marketPtr;
- MarketGoods *marketRawPtr;
- MarketGoods *marketGoodsPtr; // used to find empty slot
- short curStock, unloadQty, useEmptySlot;
- for(i=0; i<MAX_RAW; i++)
- {
- if(!raw_qty_array[i])
- continue; // without this goods
- totalDemand = 0;
- memset(empty_slot_position_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- firmSelectedPtr = firm_selected_array;
- //----------------------------------------------------------------------//
- // calculate the demand of this goods in factory
- //----------------------------------------------------------------------//
- factoryNodePtr = linked_factory_array;
- for(j=0; j<linked_factory_num; j++, factoryNodePtr++, firmSelectedPtr++)
- {
- err_when(firm_array.is_deleted(*factoryNodePtr));
- factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
- err_when(factoryPtr->firm_id != FIRM_FACTORY);
- if(factoryPtr->nation_recno!=nation_recno)
- continue; // don't unload goods to factory of other nation
- if(factoryPtr->ai_status==FACTORY_RELOCATE)
- continue; // clearing the factory stock, so no unloading
- if(factoryPtr->product_raw_id-1 == i)
- {
- totalDemand = (short) (factoryPtr->max_raw_stock_qty - factoryPtr->raw_stock_qty);
- ++*firmSelectedPtr;
- }
- }
- //----------------------------------------------------------------------//
- // calculate the demand of this goods in market
- //----------------------------------------------------------------------//
- marketNodePtr = linked_market_array;
- for(j=0; j<linked_market_num; j++, marketNodePtr++, firmSelectedPtr++)
- {
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- if(marketPtr->nation_recno!=nation_recno)
- continue; // don't unload goods to market of other nation
- if(marketPtr->ai_status==MARKET_FOR_SELL)
- continue; // clearing the market stock, so no unloading
- //---------- check the demand of this goods in the market ---------//
- marketRawPtr = marketPtr->market_raw_array[i];
- if(marketRawPtr)
- {
- err_when(marketRawPtr->product_raw_id && marketRawPtr->raw_id);
- totalDemand += (short)(marketPtr->max_stock_qty - marketRawPtr->stock_qty);
- ++*firmSelectedPtr;
- }
- else // don't have this raw, clear for empty slot
- {
- marketGoodsPtr = marketPtr->market_goods_array;
- for(k=0; k<MAX_MARKET_GOODS; k++, marketGoodsPtr++)
- {
- err_when(marketGoodsPtr->product_raw_id && marketGoodsPtr->raw_id);
- if(!marketGoodsPtr->stock_qty && !marketGoodsPtr->supply_30days())
- {
- empty_slot_position_array[j] = k;
- totalDemand += (short)marketPtr->max_stock_qty;
- ++*firmSelectedPtr;
- break;
- }
- }
- }
- }
- //----------------------------------------------------------------------//
- // distribute the stock into each factory
- //----------------------------------------------------------------------//
- curStock = raw_qty_array[i];
- factoryNodePtr = linked_factory_array;
- firmSelectedPtr = firm_selected_array;
- for(j=0; j<linked_factory_num; j++, factoryNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*factoryNodePtr));
- factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
- err_when(factoryPtr->firm_id != FIRM_FACTORY);
- err_when(factoryPtr->product_raw_id-1!=i);
-
- unloadQty = totalDemand ? (short)((factoryPtr->max_raw_stock_qty-factoryPtr->raw_stock_qty)*curStock/totalDemand + 0.5) : 0;
- unloadQty = min((short)(factoryPtr->max_raw_stock_qty-factoryPtr->raw_stock_qty), unloadQty);
- unloadQty = min(raw_qty_array[i], unloadQty);
- factoryPtr->raw_stock_qty += unloadQty;
- err_when(factoryPtr->raw_stock_qty > factoryPtr->max_raw_stock_qty);
- raw_qty_array[i] -= unloadQty;
- err_when(raw_qty_array[i] < 0);
- mprocessed_raw_qty_array[linked_mine_num+j][i] += 2;
- }
- //----------------------------------------------------------------------//
- // distribute the stock into each market
- //----------------------------------------------------------------------//
- marketNodePtr = linked_market_array;
- for(j=0; j<linked_market_num; j++, marketNodePtr, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- marketRawPtr = marketPtr->market_raw_array[i];
- if(!marketRawPtr) // using empty slot, don't set the pointer to the market_goods_array until unloadQty>0
- {
- useEmptySlot = 1;
- marketRawPtr = marketPtr->market_goods_array + empty_slot_position_array[j];
- }
- else
- useEmptySlot = 0;
- unloadQty = totalDemand ? (short)((marketPtr->max_stock_qty-marketRawPtr->stock_qty)*curStock/totalDemand + 0.5) : 0;
- unloadQty = min((short)(marketPtr->max_stock_qty-marketRawPtr->stock_qty), unloadQty);
- unloadQty = min(raw_qty_array[i], unloadQty);
- if(unloadQty)
- {
- if(useEmptySlot)
- marketPtr->set_goods(1, i+1, empty_slot_position_array[j]);
- marketRawPtr->stock_qty += unloadQty;
- err_when(marketRawPtr->stock_qty > marketPtr->max_stock_qty);
- raw_qty_array[i] -= unloadQty;
- err_when(raw_qty_array[i] < 0);
- mprocessed_raw_qty_array[linked_mine_num+linked_factory_num+j][i] += 2;
- }
- }
- }
- }
- //----------- End of function UnitMarine::harbor_unload_raw -----------//
- //--------- Begin of function UnitMarine::harbor_load_goods ---------//
- void UnitMarine::harbor_load_goods()
- {
- if(!linked_mine_num && !linked_factory_num && !linked_market_num)
- return;
- err_when(linked_mine_num+linked_factory_num+linked_market_num>MAX_LINKED_FIRM_FIRM);
- ShipStop *stopPtr = stop_array+dest_stop_id-1;
- if(stopPtr->pick_up_type == NO_PICK_UP)
- return; // return if not allowed to load any goods
- int pickUpType, goodsId;
- for(int i=0; i<MAX_PICK_UP_GOODS; i++)
- {
- if(!stopPtr->pick_up_array[i])
- continue;
- pickUpType = i+1;
- if(pickUpType>=PICK_UP_RAW_FIRST && pickUpType<=PICK_UP_RAW_LAST)
- {
- goodsId = pickUpType-PICK_UP_RAW_FIRST;
-
- if(raw_qty_array[goodsId]<carry_goods_capacity)
- harbor_load_raw(goodsId, 0, 1); // 1 -- only consider our firm
-
- if(raw_qty_array[goodsId]<carry_goods_capacity)
- harbor_load_raw(goodsId, 0, 0); // 0 -- only consider firm of other nation
- }
- else if(pickUpType>=PICK_UP_PRODUCT_FIRST && pickUpType<=PICK_UP_PRODUCT_LAST)
- {
- goodsId = pickUpType-PICK_UP_PRODUCT_FIRST;
- if(product_raw_qty_array[goodsId]<carry_goods_capacity) // 1 -- only consider our firm
- harbor_load_product(goodsId, 0, 1);
-
- if(product_raw_qty_array[goodsId]<carry_goods_capacity) // 0 -- only consider firm of other nation
- harbor_load_product(goodsId, 0, 0);
- }
- else
- err_here();
- }
- }
- //----------- End of function UnitMarine::harbor_load_goods -----------//
- //--------- Begin of function UnitMarine::harbor_auto_load_goods ---------//
- void UnitMarine::harbor_auto_load_goods()
- {
- if(!linked_mine_num && !linked_factory_num && !linked_market_num)
- return;
- err_when(linked_mine_num+linked_factory_num+linked_market_num>MAX_LINKED_FIRM_FIRM);
- int i;
- for(i=0; i<MAX_PRODUCT; i++)
- {
- if(product_raw_qty_array[i]<carry_goods_capacity)
- harbor_load_product(i, 1, 1); // 1 -- only consider our market
- }
- for(i=0; i<MAX_RAW; i++)
- {
- if(raw_qty_array[i]<carry_goods_capacity)
- harbor_load_raw(i, 1, 1); // 1 -- only consider our market
- }
- }
- //----------- End of function UnitMarine::harbor_auto_load_goods -----------//
- //--------- Begin of function UnitMarine::harbor_load_product ---------//
- // <int> considerMode - 1 only consider our market
- // - 0 only consider markets of other nation
- //
- void UnitMarine::harbor_load_product(int goodsId, int autoPickUp, int considerMode)
- {
- if(!linked_factory_num && !linked_market_num)
- return;
- if(product_raw_qty_array[goodsId]==carry_goods_capacity)
- return;
- int i;
- short totalSupply;
- short *factoryNodePtr; // point to linked_factory_array
- short *marketNodePtr; // point to linked_market_array
- char *firmSelectedPtr; // mark which firm is used (for factory and market)
- FirmFactory *factoryPtr;
- FirmMarket *marketPtr;
- MarketGoods *marketProductPtr;
- short loadQty, keepStockQty;
- totalSupply = 0;
- memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- firmSelectedPtr = firm_selected_array;
- //----------------------------------------------------------------------//
- // calculate the supply of this goods in factory
- //----------------------------------------------------------------------//
- if(linked_factory_num)
- {
- factoryPtr = (FirmFactory*) firm_array[linked_factory_array[0]];
- keepStockQty = autoPickUp ? (short) (factoryPtr->max_stock_qty/5) : 0;
- }
- factoryNodePtr = linked_factory_array;
- for(i=0; i<linked_factory_num; i++, factoryNodePtr++, firmSelectedPtr++)
- {
- if(mprocessed_product_raw_qty_array[linked_mine_num+i][goodsId]==2)
- continue;
- err_when(firm_array.is_deleted(*factoryNodePtr));
- factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
- err_when(factoryPtr->firm_id != FIRM_FACTORY);
- if(considerMode)
- {
- if(factoryPtr->nation_recno!=nation_recno)
- continue; // not our market
- }
- else
- {
- if(factoryPtr->nation_recno==nation_recno)
- continue; // not consider our market for this mode
- }
- //---------- check the supply of this goods in the factory ---------//
- if(factoryPtr->product_raw_id!=goodsId+1)
- continue; // incorrect product
- totalSupply += max((short)(factoryPtr->stock_qty-keepStockQty), 0);
- ++*firmSelectedPtr;
- }
- //----------------------------------------------------------------------//
- // calculate the supply of this goods in market
- //----------------------------------------------------------------------//
- if(linked_market_num)
- {
- marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
- keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
- }
- marketNodePtr = linked_market_array;
- for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
- {
- if(mprocessed_product_raw_qty_array[linked_mine_num+linked_factory_num+i][goodsId]==2)
- continue;
-
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- if(considerMode)
- {
- if(marketPtr->nation_recno!=nation_recno)
- continue; // not our market
- }
- else
- {
- if(marketPtr->nation_recno==nation_recno)
- continue; // not consider our market for this mode
- }
-
- //---------- check the supply of this goods in the market ---------//
- marketProductPtr = marketPtr->market_product_array[goodsId];
- if(marketProductPtr)
- {
- totalSupply += max((short)(marketProductPtr->stock_qty-keepStockQty), 0);
- ++*firmSelectedPtr;
- }
- }
- Nation *nationPtr = nation_array[nation_recno];
- int curDemand = carry_goods_capacity-product_raw_qty_array[goodsId];
- firmSelectedPtr = firm_selected_array;
- //----------------------------------------------------------------------//
- // get the stock from each factory
- //----------------------------------------------------------------------//
- if(linked_factory_num)
- {
- factoryPtr = (FirmFactory*) firm_array[linked_factory_array[0]];
- keepStockQty = autoPickUp ? (short) (factoryPtr->max_stock_qty/5) : 0;
- }
- factoryNodePtr = linked_factory_array;
- for(i=0; i<linked_factory_num; i++, factoryNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*factoryNodePtr));
- factoryPtr = (FirmFactory*) firm_array[*factoryNodePtr];
- err_when(factoryPtr->firm_id != FIRM_FACTORY);
- err_when(factoryPtr->product_raw_id-1!=goodsId);
- loadQty = max((short) (factoryPtr->stock_qty-keepStockQty), 0);
- loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
- if(factoryPtr->nation_recno!=nation_recno)
- {
- loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/PRODUCT_PRICE, loadQty) : 0;
- if(loadQty)
- nationPtr->import_goods(IMPORT_PRODUCT, factoryPtr->nation_recno, (float)loadQty*PRODUCT_PRICE);
- }
- factoryPtr->stock_qty -= loadQty;
- err_when(factoryPtr->stock_qty < 0);
- product_raw_qty_array[goodsId] += loadQty;
- err_when(product_raw_qty_array[goodsId] > carry_goods_capacity);
- }
- //----------------------------------------------------------------------//
- // get the stock from each market
- //----------------------------------------------------------------------//
- if(linked_market_num)
- {
- marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
- keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
- }
- marketNodePtr = linked_market_array;
- for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- marketProductPtr = marketPtr->market_product_array[goodsId];
- loadQty = max((short) marketProductPtr->stock_qty-keepStockQty, 0);
- loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
- if(marketPtr->nation_recno!=nation_recno)
- {
- loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/PRODUCT_PRICE, loadQty) : 0;
- if(loadQty)
- nationPtr->import_goods(IMPORT_PRODUCT, marketPtr->nation_recno, (float)loadQty * PRODUCT_PRICE);
- }
- marketProductPtr->stock_qty -= loadQty;
- err_when(marketProductPtr->stock_qty < 0);
- product_raw_qty_array[goodsId] += loadQty;
- err_when(product_raw_qty_array[goodsId] > carry_goods_capacity);
- }
- }
- //----------- End of function UnitMarine::harbor_load_product -----------//
- //--------- Begin of function UnitMarine::harbor_load_raw ---------//
- // <int> considerMode - 1 only consider our market
- // - 0 only consider markets of other nation
- //
- void UnitMarine::harbor_load_raw(int goodsId, int autoPickUp, int considerMode)
- {
- if(!linked_mine_num && !linked_market_num)
- return;
- if(raw_qty_array[goodsId]==carry_goods_capacity)
- return;
- int i;
- short totalSupply;
- short *mineNodePtr; // point to linked_factory_array
- short *marketNodePtr; // point to linked_market_array
- char *firmSelectedPtr; // mark which firm is used (for factory and market)
- FirmMine *minePtr;
- FirmMarket *marketPtr;
- MarketGoods *marketRawPtr;
- short loadQty, keepStockQty;
- totalSupply = 0;
- memset(firm_selected_array, 0, sizeof(char)*MAX_LINKED_FIRM_FIRM);
- firmSelectedPtr = firm_selected_array;
- //----------------------------------------------------------------------//
- // calculate the supply of this goods in mine
- //----------------------------------------------------------------------//
- if(linked_mine_num)
- {
- minePtr = (FirmMine*) firm_array[linked_mine_array[0]];
- keepStockQty = autoPickUp ? (short) (minePtr->max_stock_qty/5) : 0;
- }
- mineNodePtr = linked_mine_array;
- for(i=0; i<linked_mine_num; i++, mineNodePtr++, firmSelectedPtr++)
- {
- if(mprocessed_raw_qty_array[i][goodsId]==2)
- continue;
- err_when(firm_array.is_deleted(*mineNodePtr));
- minePtr = (FirmMine*) firm_array[*mineNodePtr];
- err_when(minePtr->firm_id != FIRM_MINE);
- if(considerMode)
- {
- if(minePtr->nation_recno!=nation_recno)
- continue; // not our market
- }
- else
- {
- if(minePtr->nation_recno==nation_recno)
- continue; // not consider our market for this mode
- }
- //---------- check the supply of this goods in the mine ---------//
- if(minePtr->raw_id!=goodsId+1)
- continue; // incorrect goods
- totalSupply += max((short)(minePtr->stock_qty-keepStockQty), 0);
- ++*firmSelectedPtr;
- }
- //----------------------------------------------------------------------//
- // calculate the supply of this goods in market
- //----------------------------------------------------------------------//
- if(linked_market_num)
- {
- marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
- keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
- }
- marketNodePtr = linked_market_array;
- for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
- {
- if(mprocessed_raw_qty_array[linked_mine_num+linked_factory_num+i][goodsId]==2)
- continue;
-
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- if(considerMode)
- {
- if(marketPtr->nation_recno!=nation_recno)
- continue; // not our market
- }
- else
- {
- if(marketPtr->nation_recno==nation_recno)
- continue; // not consider our market for this mode
- }
-
- //---------- check the supply of this goods in the market ---------//
- marketRawPtr = marketPtr->market_raw_array[goodsId];
- if(marketRawPtr)
- {
- totalSupply += max((short)(marketRawPtr->stock_qty-keepStockQty), 0);
- ++*firmSelectedPtr;
- }
- }
- Nation *nationPtr = nation_array[nation_recno];
- int curDemand = carry_goods_capacity-raw_qty_array[goodsId];
- firmSelectedPtr = firm_selected_array;
- //----------------------------------------------------------------------//
- // get the stock from each mine
- //----------------------------------------------------------------------//
- if(linked_mine_num)
- {
- minePtr = (FirmMine*) firm_array[linked_mine_array[0]];
- keepStockQty = autoPickUp ? (short) (minePtr->max_stock_qty/5) : 0;
- }
- mineNodePtr = linked_mine_array;
- for(i=0; i<linked_mine_num; i++, mineNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*mineNodePtr));
- minePtr = (FirmMine*) firm_array[*mineNodePtr];
- err_when(minePtr->firm_id != FIRM_MINE);
- err_when(minePtr->raw_id-1!=goodsId);
- loadQty = max((short) (minePtr->stock_qty-keepStockQty), 0);
- loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
- if(minePtr->nation_recno!=nation_recno)
- {
- loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/RAW_PRICE, loadQty) : 0;
- if(loadQty)
- nationPtr->import_goods(IMPORT_RAW, minePtr->nation_recno, (float)loadQty*RAW_PRICE);
- }
- minePtr->stock_qty -= loadQty;
- err_when(minePtr->stock_qty < 0);
- raw_qty_array[goodsId] += loadQty;
- err_when(raw_qty_array[goodsId] > carry_goods_capacity);
- }
- //----------------------------------------------------------------------//
- // get the stock from each market
- //----------------------------------------------------------------------//
- if(linked_market_num)
- {
- marketPtr = (FirmMarket*) firm_array[linked_market_array[0]];
- keepStockQty = autoPickUp ? (short) (marketPtr->max_stock_qty/5) : 0;
- }
- marketNodePtr = linked_market_array;
- for(i=0; i<linked_market_num; i++, marketNodePtr++, firmSelectedPtr++)
- {
- if(!(*firmSelectedPtr))
- continue;
- err_when(firm_array.is_deleted(*marketNodePtr));
- marketPtr = (FirmMarket*) firm_array[*marketNodePtr];
- err_when(marketPtr->firm_id != FIRM_MARKET);
- marketRawPtr = marketPtr->market_raw_array[goodsId];
- loadQty = max((short) marketRawPtr->stock_qty-keepStockQty, 0);
- loadQty = totalSupply ? min((short) ((float)loadQty*curDemand/totalSupply), loadQty) : 0;
- if(marketPtr->nation_recno!=nation_recno)
- {
- loadQty = (nationPtr->cash>0) ? (short) min(nationPtr->cash/RAW_PRICE, loadQty) : 0;
- if(loadQty)
- nationPtr->import_goods(IMPORT_RAW, marketPtr->nation_recno, (float)loadQty * RAW_PRICE);
- }
- marketRawPtr->stock_qty -= loadQty;
- err_when(marketRawPtr->stock_qty < 0);
- raw_qty_array[goodsId] += loadQty;
- err_when(raw_qty_array[goodsId] > carry_goods_capacity);
- }
- }
- //----------- End of function UnitMarine::harbor_load_raw -----------//
|