From 598709f33dcaeee0e54574442c9b54bb8b3e38f4 Mon Sep 17 00:00:00 2001 From: Wanne Date: Tue, 21 Apr 2009 20:27:56 +0000 Subject: [PATCH] - Added Dealtar's and Zilpin's Airport Externalization - Needed GameDir files are already committet to SVN GameDir git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@2759 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Init.cpp | 13 + Laptop/BobbyR.cpp | 59 +++ Laptop/BobbyRMailOrder.cpp | 153 +++++- Laptop/BobbyRMailOrder.h | 2 +- Laptop/BobbyRShipments.cpp | 128 ++++- Laptop/Laptop.vcproj | 12 + Laptop/Laptop_2005Express.vcproj | 16 + Laptop/Laptop_VS2008.vcproj | 16 + Laptop/PostalService.cpp | 730 ++++++++++++++++++++++++++++ Laptop/PostalService.h | 252 ++++++++++ Laptop/XML_DeliveryMethods.cpp | 266 ++++++++++ Laptop/XML_ShippingDestinations.cpp | 203 ++++++++ Laptop/email.cpp | 36 ++ SaveLoadGame.cpp | 21 + SaveLoadScreen.cpp | 5 + Strategic/Game Event Hook.cpp | 5 + Strategic/Game Event Hook.h | 1 + Strategic/Game Events.cpp | 1 + Tactical/XML.h | 6 + ja2_2005Express.vcproj | 6 +- ja2_VS2008.vcproj | 2 +- 21 files changed, 1893 insertions(+), 40 deletions(-) create mode 100644 Laptop/PostalService.cpp create mode 100644 Laptop/PostalService.h create mode 100644 Laptop/XML_DeliveryMethods.cpp create mode 100644 Laptop/XML_ShippingDestinations.cpp diff --git a/Init.cpp b/Init.cpp index c7907a99..d0530587 100644 --- a/Init.cpp +++ b/Init.cpp @@ -569,6 +569,19 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) if(!ReadInRoamingInfo(fileName)) return FALSE; + // Dealtar: Read in shipping destinations and delivery methods + strcpy(fileName, directoryName); + strcat(fileName, SHIPPINGDESTINATIONSFILENAME); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + if(!ReadInShippingDestinations(fileName)) + return FALSE; + strcpy(fileName, directoryName); + strcat(fileName, DELIVERYMETHODSFILENAME); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + if(!ReadInDeliveryMethods(fileName)) + return FALSE; + + return TRUE; } diff --git a/Laptop/BobbyR.cpp b/Laptop/BobbyR.cpp index c5bbc605..66ca4aea 100644 --- a/Laptop/BobbyR.cpp +++ b/Laptop/BobbyR.cpp @@ -21,6 +21,7 @@ #include "armsdealerinvinit.h" #include "GameSettings.h" #include "message.h" + #include "postalservice.h" #endif @@ -174,6 +175,17 @@ UINT8 gubBobbyRPages[]={ LAPTOP_MODE_BOBBY_R_AMMO, LAPTOP_MODE_BOBBY_R_ARMOR}; +//Dealtar's Airport Externalization. +BOOLEAN gfBobbyRInitialized = 0; +extern CPostalService gPostalService; +extern UINT8 guiNumOfDisplayedCities; +extern vector < PDestinationStruct > gDestinationTable; +extern vector < PShipmentStruct > gShipmentTable; +extern MOUSE_REGION *gSelectedDropDownRegion; +extern MOUSE_REGION *gSelectedScrollAreaDropDownRegion; +extern void BobbyRDeliveryCallback(RefToCShipmentManipulator ShipmentManipulator); +//End Dealtar's Airport Externalization. + //Bobby's Sign menu mouse regions MOUSE_REGION gSelectedBobbiesSignMenuRegion[ BOBBIES_NUMBER_SIGNS ]; @@ -189,6 +201,9 @@ void SimulateBobbyRayCustomer(STORE_INVENTORY *pInventoryArray, BOOLEAN fUsed); void GameInitBobbyR() { + //Dealtar's Airport Externalization. + //Originally, this function was empty! + gPostalService.RegisterDeliveryCallback(0, BobbyRDeliveryCallback); } @@ -197,6 +212,50 @@ BOOLEAN EnterBobbyR() VOBJECT_DESC VObjectDesc; UINT8 i; + //Dealtar's Airport Externalization. + // Update the destination and shipment tables upon entering Bobby R + if (!gDestinationTable.empty()) + { + gDestinationTable.erase(gDestinationTable.begin(), gDestinationTable.end()); + } + + if (!gShipmentTable.empty()) + { + gShipmentTable.erase(gShipmentTable.begin(), gShipmentTable.end()); + } + + RefToDestinationListIterator dli = gPostalService.LookupDestinationList().begin(); + + while (dli != gPostalService.LookupDestinationList().end()) + { + gDestinationTable.push_back(&DESTINATION(dli)); + dli++; + + } + + RefToShipmentListIterator sli = gPostalService.LookupShipmentList().begin(); + + while (sli != gPostalService.LookupShipmentList().end()) + { + gShipmentTable.push_back(&SHIPMENT(sli)); + sli++; + } + + // Dealtar: The following code had to be put here, because GameInitBobbyR() is called + // before XML data is read into gPostalService due to the screen order in + // screens.cpp -> GameScreens[] + if (!gfBobbyRInitialized) + { + gfBobbyRInitialized = TRUE; + gSelectedDropDownRegion = new MOUSE_REGION[gPostalService.LookupDestinationList().size()]; + gSelectedScrollAreaDropDownRegion = new MOUSE_REGION[gPostalService.LookupDestinationList().size()]; + int x = gPostalService.LookupDestinationList().size(); + guiNumOfDisplayedCities = (x < 10) ? x : 10; + //gDestinationTable.resize(gPostalService.LookupDestinationList().size()); + } + //End Dealtar's Airport Externalization. + + // an array of mouse regions for the bobbies signs. Top Left corner, bottom right corner UINT16 usMouseRegionPosArray[] = {BOBBIES_USED_SIGN_X, BOBBIES_USED_SIGN_Y, BOBBIES_USED_SIGN_X+BOBBIES_USED_SIGN_WIDTH, BOBBIES_USED_SIGN_Y+BOBBIES_USED_SIGN_HEIGHT, BOBBIES_MISC_SIGN_X, BOBBIES_MISC_SIGN_Y, BOBBIES_MISC_SIGN_X+BOBBIES_MISC_SIGN_WIDTH, BOBBIES_MISC_SIGN_Y+BOBBIES_MISC_SIGN_HEIGHT, diff --git a/Laptop/BobbyRMailOrder.cpp b/Laptop/BobbyRMailOrder.cpp index 01843ea6..12f4213e 100644 --- a/Laptop/BobbyRMailOrder.cpp +++ b/Laptop/BobbyRMailOrder.cpp @@ -23,6 +23,9 @@ #include "Multi Language Graphic Utils.h" #include "strategic.h" #include "strategicmap.h" + #include "isometric utils.h" + #include "postalservice.h" + #include #endif #include "Strategic Event Handler.h" @@ -216,6 +219,9 @@ enum #define BOBBYR_PACKAXGE_WEIGHT_Y LAPTOP_SCREEN_WEB_UL_Y + 249 #define BOBBYR_PACKAXGE_WEIGHT_WIDTH 188 +//Dealtar's Airport Externalization. +#define BOBBYR_SENDER_ID 0 +#define JOHN_KULBA_SENDER_ID 1 UINT16 gShippingSpeedAreas[] = {585, 218 + LAPTOP_SCREEN_WEB_DELTA_Y, 585, 238 + LAPTOP_SCREEN_WEB_DELTA_Y, @@ -240,7 +246,7 @@ INT32 giGrandTotal; UINT32 guiShippingCost; UINT32 guiSubTotal; -UINT8 gubSelectedLight; +UINT8 gubSelectedLight=0; BOOLEAN gfDrawConfirmOrderGrpahic; BOOLEAN gfDestroyConfirmGrphiArea; @@ -296,12 +302,16 @@ MOUSE_REGION gSelectedConfirmOrderRegion; void SelectConfirmOrderRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); //mouse region for the drop down city location area -MOUSE_REGION gSelectedDropDownRegion[ BOBBYR_ORDER_NUM_SHIPPING_CITIES ]; +//MOUSE_REGION gSelectedDropDownRegion[ BOBBYR_ORDER_NUM_SHIPPING_CITIES ]; +//Dealtar's Airport Externalization. +MOUSE_REGION *gSelectedDropDownRegion; void SelectDropDownRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); void SelectDropDownMovementCallBack(MOUSE_REGION * pRegion, INT32 iReason ); //mouse region for scroll area for the drop down city location area -MOUSE_REGION gSelectedScrollAreaDropDownRegion[BOBBYR_ORDER_NUM_SHIPPING_CITIES]; +//MOUSE_REGION gSelectedScrollAreaDropDownRegion[BOBBYR_ORDER_NUM_SHIPPING_CITIES]; +//Dealtar's Airport Externalization. +MOUSE_REGION *gSelectedScrollAreaDropDownRegion; void SelectScrollAreaDropDownRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); void SelectScrollAreaDropDownMovementCallBack(MOUSE_REGION * pRegion, INT32 iReason ); @@ -322,6 +332,18 @@ void SelectTitleLinkRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); MOUSE_REGION gSelectedUpDownArrowOnScrollAreaRegion[2]; void SelectUpDownArrowOnScrollAreaRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason ); +//Dealtar's Airport Externalization. +UINT16 gusCurShipmentDestinationID; +extern CPostalService gPostalService; +UINT8 guiNumOfDisplayedCities=0; +vector gDestinationTable; +vector gShipmentTable; +void BobbyRDeliveryCallback(RefToCShipmentManipulator ShipmentManipulator) +{ + // ScreenMsg(FONT_MCOLOR_RED, MSG_DEBUG, L"Shipment from Bobby Ray has arrived at %s!", ShipmentManipulator.GetDestination().wstrName.c_str()); + gusCurShipmentDestinationID = ShipmentManipulator.GetDestination().usID; + AddEmail( BOBBYR_SHIPMENT_ARRIVED, BOBBYR_SHIPMENT_ARRIVED_LENGTH, BOBBY_R, GetWorldTotalMin(), -1 ); +} BOOLEAN DrawShippingSpeedLights(UINT8 ubSelectedLight); @@ -790,8 +812,17 @@ void BtnBobbyRAcceptOrderCallback(GUI_BUTTON *btn,INT32 reason) { CHAR16 zTemp[ 128 ]; + //Dealtar's Airport Externalization. + /*Old Code: //if the city is Drassen, and the airport sector is player controlled if( gbSelectedCity == BR_DRASSEN && !StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_B13 ) ].fEnemyControlled || is_client ) + * Dealtar's New Code: */ + //if the selected destination's sector is player controlled + if( (gDestinationTable[gbSelectedCity]->ubMapX >= 0 || + gDestinationTable[gbSelectedCity]->ubMapY >= 0 || + gDestinationTable[gbSelectedCity]->sGridNo >= 0) && + !StrategicMap[ CALCULATE_STRATEGIC_INDEX(gDestinationTable[gbSelectedCity]->ubMapX, gDestinationTable[gbSelectedCity]->ubMapY) ].fEnemyControlled ) + //End Dealtar's Code. { //Quick hack to bypass the confirmation box ConfirmBobbyRPurchaseMessageBoxCallBack( MSG_BOX_RETURN_YES ); @@ -1091,6 +1122,8 @@ void DisplayShippingCosts( BOOLEAN fCalledFromOrderPage, INT32 iSubTotal, UINT16 } else { + //Dealtar's Airport Externalization. + /* Old code: UINT16 usStandardCost; switch( gpNewBobbyrShipments[ iOrderNum ].ubDeliveryMethod ) @@ -1110,6 +1143,21 @@ void DisplayShippingCosts( BOOLEAN fCalledFromOrderPage, INT32 iSubTotal, UINT16 } iShippingCost = (INT32)( ( gpNewBobbyrShipments[ iOrderNum ].uiPackageWeight / (FLOAT)10 ) * usStandardCost + .5 ); + * Dealtar's Code: */ + UINT32 uiPackageWeight=0; + + ShipmentPackageList::iterator spi = gShipmentTable[iOrderNum]->ShipmentPackages.begin(); + + while(spi != gShipmentTable[iOrderNum]->ShipmentPackages.end()) + { + uiPackageWeight += Item[((ShipmentPackageStruct&)*spi).usItemIndex].ubWeight; + spi++; + } + + uiPackageWeight = uiPackageWeight > 20 ? uiPackageWeight : 20; + + iShippingCost = (INT32)( ( uiPackageWeight / (FLOAT)10 ) * gShipmentTable[iOrderNum]->pDestinationDeliveryInfo->usDestinationFee + .5 ); + } @@ -1327,8 +1375,13 @@ BOOLEAN CreateDestroyBobbyRDropDown( UINT8 ubDropDownAction ) //the scroll area itself usPosX = BOBBYR_SCROLL_AREA_X; usPosY = BOBBYR_SCROLL_UP_ARROW_Y + BOBBYR_SCROLL_ARROW_HEIGHT; + //Dealtar's Airport Externalization. + /* usHeight = BOBBYR_SCROLL_AREA_HEIGHT_MINUS_ARROWS / BOBBYR_ORDER_NUM_SHIPPING_CITIES; for(i=0; i BOBBYR_ORDER_NUM_SHIPPING_CITIES ) gubCityAtTopOfList = BOBBYR_ORDER_NUM_SHIPPING_CITIES - BOBBYR_NUM_DISPLAYED_CITIES - 1; + */ + if( gubCityAtTopOfList+guiNumOfDisplayedCities > (UINT8)gPostalService.LookupDestinationList().size() ) + gubCityAtTopOfList = gPostalService.LookupDestinationList().size() - guiNumOfDisplayedCities - 1; + //Display the list of cities usPosY = BOBBYR_CITY_START_LOCATION_Y + 5; + /* for( i=gubCityAtTopOfList; i< gubCityAtTopOfList+BOBBYR_NUM_DISPLAYED_CITIES; i++) { DrawTextToScreen( *(BobbyROrderLocations[i].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, usPosY, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); usPosY += usFontHeight + 2; } + */ + for( i=gubCityAtTopOfList; i< gubCityAtTopOfList+guiNumOfDisplayedCities; i++) + { + DrawTextToScreen( (STR16)gDestinationTable[i]->wstrName.c_str() , BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, usPosY, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + usPosY += usFontHeight + 2; + } if( ubCityNumber != 255 ) usPosY = (usFontHeight + 2) * (ubCityNumber - gubCityAtTopOfList) + BOBBYR_CITY_START_LOCATION_Y; @@ -1579,10 +1647,17 @@ void DrawSelectedCity( UINT8 ubCityNumber ) ColorFillVideoSurfaceArea( FRAME_BUFFER, BOBBYR_CITY_START_LOCATION_X+4, usPosY+4, BOBBYR_CITY_START_LOCATION_X+BOBBYR_DROP_DOWN_WIDTH-4, usPosY+usFontHeight+6, Get16BPPColor( FROMRGB( 200, 169, 87 ) ) ); SetFontShadow(NO_SHADOW); + /* if( ubCityNumber == 255 ) DrawTextToScreen( *(BobbyROrderLocations[ 0 ].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, (UINT16)(usPosY+5), 0, BOBBYR_DROPDOWN_FONT, BOBBYR_FONT_BLACK, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); else DrawTextToScreen( *(BobbyROrderLocations[ubCityNumber].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, (UINT16)(usPosY+5), 0, BOBBYR_DROPDOWN_FONT, BOBBYR_FONT_BLACK, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + */ + if( ubCityNumber == 255 ) + DrawTextToScreen( (STR16)gDestinationTable[0]->wstrName.c_str(), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, (UINT16)(usPosY+5), 0, BOBBYR_DROPDOWN_FONT, BOBBYR_FONT_BLACK, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + else + DrawTextToScreen( (STR16)gDestinationTable[ubCityNumber]->wstrName.c_str(), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, (UINT16)(usPosY+5), 0, BOBBYR_DROPDOWN_FONT, BOBBYR_FONT_BLACK, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + SetFontShadow(DEFAULT_SHADOW); @@ -1608,7 +1683,8 @@ void DisplayShippingLocationCity() if( gbSelectedCity == -1 ) DrawTextToScreen( BobbyROrderFormText[BOBBYR_SELECT_DEST], BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); else - DrawTextToScreen( *(BobbyROrderLocations[gbSelectedCity].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); +// DrawTextToScreen( *(BobbyROrderLocations[gbSelectedCity].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); + DrawTextToScreen( (STR16)gDestinationTable[gbSelectedCity]->wstrName.c_str(), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED ); DisplayShippingCosts( TRUE, 0, BOBBYR_ORDERGRID_X, BOBBYR_ORDERGRID_Y, -1 ); @@ -1624,7 +1700,8 @@ void DisplayShippingLocationCity() if( gbSelectedCity != -1 ) { - swprintf( sTemp, L"%d", ( INT32 )(BobbyROrderLocations[gbSelectedCity].usOverNightExpress/GetWeightBasedOnMetricOption( 1 ) ) ); +// swprintf( sTemp, L"%d", ( INT32 )(BobbyROrderLocations[gbSelectedCity].usOverNightExpress/GetWeightBasedOnMetricOption( 1 ) ) ); + swprintf( sTemp, L"%d", ( INT32 )(gPostalService.GetDestinationFee(0, gDestinationTable[gbSelectedCity]->usID) / GetWeightBasedOnMetricOption( 1 ) ) ); InsertCommasForDollarFigure( sTemp ); InsertDollarSignInToString( sTemp ); } @@ -1634,7 +1711,8 @@ void DisplayShippingLocationCity() if( gbSelectedCity != -1 ) { - swprintf( sTemp, L"%d", ( INT32 )( BobbyROrderLocations[gbSelectedCity].us2DaysService / GetWeightBasedOnMetricOption( 1 ) ) ); +// swprintf( sTemp, L"%d", ( INT32 )( BobbyROrderLocations[gbSelectedCity].us2DaysService / GetWeightBasedOnMetricOption( 1 ) ) ); + swprintf( sTemp, L"%d", ( INT32 )(gPostalService.GetDestinationFee(1, gDestinationTable[gbSelectedCity]->usID) / GetWeightBasedOnMetricOption( 1 ) ) ); InsertCommasForDollarFigure( sTemp ); InsertDollarSignInToString( sTemp ); } @@ -1644,7 +1722,8 @@ void DisplayShippingLocationCity() if( gbSelectedCity != -1 ) { - swprintf( sTemp, L"%d", (INT32 )( BobbyROrderLocations[gbSelectedCity].usStandardService / GetWeightBasedOnMetricOption( 1 ) ) ); +// swprintf( sTemp, L"%d", (INT32 )( BobbyROrderLocations[gbSelectedCity].usStandardService / GetWeightBasedOnMetricOption( 1 ) ) ); + swprintf( sTemp, L"%d", ( INT32 )(gPostalService.GetDestinationFee(2, gDestinationTable[gbSelectedCity]->usID) / GetWeightBasedOnMetricOption( 1 ) ) ); InsertCommasForDollarFigure( sTemp ); InsertDollarSignInToString( sTemp ); } @@ -1745,7 +1824,7 @@ void SelectScrollAreaDropDownRegionCallBack(MOUSE_REGION * pRegion, INT32 iReaso if( ubCityNum > gbSelectedCity ) { gbSelectedCity++; - if( ( gbSelectedCity - gubCityAtTopOfList ) >= BOBBYR_NUM_DISPLAYED_CITIES ) + if( ( gbSelectedCity - gubCityAtTopOfList ) >= guiNumOfDisplayedCities ) //BOBBYR_NUM_DISPLAYED_CITIES gubCityAtTopOfList++; } @@ -1767,7 +1846,7 @@ void SelectScrollAreaDropDownRegionCallBack(MOUSE_REGION * pRegion, INT32 iReaso if( ubCityNum > gbSelectedCity ) { gbSelectedCity++; - if( ( gbSelectedCity - gubCityAtTopOfList ) >= BOBBYR_NUM_DISPLAYED_CITIES ) + if( ( gbSelectedCity - gubCityAtTopOfList ) >= guiNumOfDisplayedCities ) //BOBBYR_NUM_DISPLAYED_CITIES gubCityAtTopOfList++; } @@ -1803,8 +1882,8 @@ void SelectScrollAreaDropDownMovementCallBack(MOUSE_REGION * pRegion, INT32 reas if( ubCityNum > gbSelectedCity ) { gbSelectedCity = ubCityNum; - if( ( gbSelectedCity - gubCityAtTopOfList ) >= BOBBYR_NUM_DISPLAYED_CITIES ) - gubCityAtTopOfList = gbSelectedCity - BOBBYR_NUM_DISPLAYED_CITIES + 1; + if( ( gbSelectedCity - gubCityAtTopOfList ) >= guiNumOfDisplayedCities ) //BOBBYR_NUM_DISPLAYED_CITIES + gubCityAtTopOfList = gbSelectedCity - guiNumOfDisplayedCities + 1; //BOBBYR_NUM_DISPLAYED_CITIES } gubDropDownAction = BR_DROP_DOWN_DISPLAY; @@ -1826,12 +1905,13 @@ void SelectUpDownArrowOnScrollAreaRegionCallBack(MOUSE_REGION * pRegion, INT32 i if( ubUpArrow ) { - if( gbSelectedCity < BOBBYR_ORDER_NUM_SHIPPING_CITIES-1 ) + //if( gbSelectedCity < BOBBYR_ORDER_NUM_SHIPPING_CITIES-1 ) + if( gbSelectedCity < (INT8)gPostalService.LookupDestinationList().size()-1 ) { gbSelectedCity++; } - if( ( gbSelectedCity - gubCityAtTopOfList ) >= BOBBYR_NUM_DISPLAYED_CITIES ) + if( ( gbSelectedCity - gubCityAtTopOfList ) >= guiNumOfDisplayedCities ) //BOBBYR_NUM_DISPLAYED_CITIES { gubCityAtTopOfList++; } @@ -1871,7 +1951,8 @@ void DrawGoldRectangle( INT8 bCityNum ) usWidth = BOBBYR_SCROLL_AREA_WIDTH - 5; usTempHeight = ( BOBBYR_SCROLL_AREA_HEIGHT - 2 * BOBBYR_SCROLL_ARROW_HEIGHT ) - 8; - usHeight = usTempHeight / (BOBBYR_ORDER_NUM_SHIPPING_CITIES+1); + //usHeight = usTempHeight / (BOBBYR_ORDER_NUM_SHIPPING_CITIES+1); + usHeight = usTempHeight / (gPostalService.LookupDestinationList().size()+1); usPosY = usTempPosY + (UINT16)( ( ( BOBBYR_SCROLL_AREA_HEIGHT - 2 * BOBBYR_SCROLL_ARROW_HEIGHT ) / (FLOAT)(BOBBYR_ORDER_NUM_SHIPPING_CITIES +1) ) * bCityNum ); @@ -1926,6 +2007,8 @@ UINT32 CalcCostFromWeightOfPackage( UINT8 ubTypeOfService ) */ Assert ( ubTypeOfService < 3); + //Dealtar's Airport Externalization + /* switch( ubTypeOfService ) { case 0: @@ -1941,6 +2024,9 @@ UINT32 CalcCostFromWeightOfPackage( UINT8 ubTypeOfService ) default: usStandardCost = 0; } + */ + usStandardCost = gPostalService.GetDestinationFee(ubTypeOfService, gDestinationTable[gbSelectedCity]->usID); + //Get the actual weight ( either in lbs or metric ) /// usStandardCost = (UINT16) GetWeightBasedOnMetricOption( usStandardCost ); @@ -2015,7 +2101,8 @@ INT8 CalculateOrderDelay( UINT8 ubSelectedService ) void PurchaseBobbyOrder() { //if the shipment is going to Drassen, add the inventory - if( gbSelectedCity == BR_DRASSEN || gbSelectedCity == BR_MEDUNA ) +// if( gbSelectedCity == BR_DRASSEN || gbSelectedCity == BR_MEDUNA ) + if(gbSelectedCity >= 0) { // BobbyRayOrderStruct *pBobbyRayPurchase; // UINT32 uiResetTimeSec; @@ -2070,7 +2157,8 @@ void PurchaseBobbyOrder() */ //add the delivery - AddNewBobbyRShipment( BobbyRayPurchases, gbSelectedCity, gubSelectedLight, TRUE, CalcPackageTotalWeight() ); + //AddNewBobbyRShipment( BobbyRayPurchases, gbSelectedCity, gubSelectedLight, TRUE, CalcPackageTotalWeight() ); + AddNewBobbyRShipment( BobbyRayPurchases, gDestinationTable[gbSelectedCity]->usID, gubSelectedLight, TRUE, CalcPackageTotalWeight() ); /* //get the length of time to receive the shipment @@ -2156,7 +2244,8 @@ void AddJohnsGunShipment() // AddFutureDayStrategicEvent( EVENT_BOBBYRAY_PURCHASE, (8 + Random(4) ) * 60, cnt, bDaysAhead ); //add the delivery ( weight is not needed as it will not be displayed ) - AddNewBobbyRShipment( Temp, BR_DRASSEN, bDaysAhead, FALSE, 0 ); + //AddNewBobbyRShipment( Temp, BR_DRASSEN, bDaysAhead, FALSE, 0 ); + AddNewBobbyRShipment( Temp, 3, bDaysAhead, FALSE, 1 ); } @@ -2286,6 +2375,8 @@ void DrawBobbyROrderTitle() } +//Dealtar's Airport Externalization +/* BOOLEAN AddNewBobbyRShipment( BobbyRayPurchaseStruct *pPurchaseStruct, UINT8 ubDeliveryLoc, UINT8 ubDeliveryMethod, BOOLEAN fPruchasedFromBobbyR, UINT32 uiPackageWeight ) { INT32 iCnt; @@ -2381,6 +2472,26 @@ BOOLEAN AddNewBobbyRShipment( BobbyRayPurchaseStruct *pPurchaseStruct, UINT8 ubD return( TRUE ); } +*/ +BOOLEAN AddNewBobbyRShipment( BobbyRayPurchaseStruct *pPurchaseStruct, UINT16 usDeliveryLoc, UINT8 ubDeliveryMethod, BOOLEAN fPurchasedFromBobbyR, UINT32 uiPackageWeight ) +{ + UINT16 usID; + + if(fPurchasedFromBobbyR) + usID = gPostalService.CreateNewShipment(usDeliveryLoc, ubDeliveryMethod, 0); + else + usID = gPostalService.CreateNewShipment(usDeliveryLoc, 2, 1); + + for(int i=0; i < MAX_PURCHASE_AMOUNT && pPurchaseStruct[i].usItemIndex > 0; i++) + { + gPostalService.AddPackageToShipment(usID, pPurchaseStruct[i].usItemIndex, pPurchaseStruct[i].ubNumberPurchased, pPurchaseStruct[i].bItemQuality); + } + + gPostalService.SendShipment(usID); + + return TRUE; +} + UINT16 CountNumberOfBobbyPurchasesThatAreInTransit() { diff --git a/Laptop/BobbyRMailOrder.h b/Laptop/BobbyRMailOrder.h index 6f364f21..48ed7a25 100644 --- a/Laptop/BobbyRMailOrder.h +++ b/Laptop/BobbyRMailOrder.h @@ -72,7 +72,7 @@ typedef struct extern NewBobbyRayOrderStruct *gpNewBobbyrShipments; extern INT32 giNumberOfNewBobbyRShipment; -BOOLEAN AddNewBobbyRShipment( BobbyRayPurchaseStruct *pPurchaseStruct, UINT8 ubDeliveryLoc, UINT8 ubDeliveryMethod, BOOLEAN fPruchasedFromBobbyR, UINT32 uiPackageWeight ); +BOOLEAN AddNewBobbyRShipment( BobbyRayPurchaseStruct *pPurchaseStruct, UINT16 usDeliveryLoc, UINT8 ubDeliveryMethod, BOOLEAN fPurchasedFromBobbyR, UINT32 uiPackageWeight ); UINT16 CountNumberOfBobbyPurchasesThatAreInTransit(); diff --git a/Laptop/BobbyRShipments.cpp b/Laptop/BobbyRShipments.cpp index 3ba6d75d..5d360880 100644 --- a/Laptop/BobbyRShipments.cpp +++ b/Laptop/BobbyRShipments.cpp @@ -14,6 +14,7 @@ #include "wordwrap.h" #include "strategic.h" #include "strategicmap.h" + #include "PostalService.h" #endif @@ -104,6 +105,8 @@ void RemovePreviousShipmentsMouseRegions(); void CreatePreviousShipmentsMouseRegions(); INT32 CountNumberValidShipmentForTheShipmentsPage(); //ppp +extern CPostalService gPostalService; +extern vector gShipmentTable; // @@ -151,6 +154,7 @@ BOOLEAN EnterBobbyRShipments() giBobbyRShipmentSelectedShipment = -1; + /* //if there are shipments if( giNumberOfNewBobbyRShipment != 0 ) { @@ -170,6 +174,26 @@ BOOLEAN EnterBobbyRShipments() giBobbyRShipmentSelectedShipment = iCnt; } } + */ + //if there are shipments + if( gShipmentTable.size() != 0 ) + { + INT32 iCnt=0; + + //get the first shipment # + vector::iterator& psi = gShipmentTable.begin(); + + while(psi != gShipmentTable.end()) + { + if(((PShipmentStruct)*psi)->ShipmentStatus == SHIPMENT_INTRANSIT) + { + giBobbyRShipmentSelectedShipment = iCnt; + } + psi++; + iCnt++; + } + } + CreatePreviousShipmentsMouseRegions(); @@ -205,6 +229,13 @@ void RenderBobbyRShipments() { // HVOBJECT hPixHandle; + // Dealtar: this must be static as this is accessed after this function has returned + static BobbyRayPurchaseStruct brps[MAX_PURCHASE_AMOUNT]; + for(int i = 0; i < MAX_PURCHASE_AMOUNT; i++) + { + memset(&brps[i], 0, sizeof(BobbyRayPurchaseStruct)); + } + DrawBobbyRWoodBackground(); DrawBobbyROrderTitle(); @@ -214,6 +245,43 @@ void RenderBobbyRShipments() DisplayShipmentGrid(); + if(giBobbyRShipmentSelectedShipment != -1) + { + RefToShipmentPackageListIterator spli = gShipmentTable[giBobbyRShipmentSelectedShipment]->ShipmentPackages.begin(); + int j; + for(int i = 0; i < gShipmentTable[giBobbyRShipmentSelectedShipment]->ShipmentPackages.size(); i++, spli++) + { + brps[i].bItemQuality = ((ShipmentPackageStruct)*spli).bItemQuality; + brps[i].ubNumberPurchased = ((ShipmentPackageStruct)*spli).ubNumber; + brps[i].usItemIndex = ((ShipmentPackageStruct)*spli).usItemIndex; + brps[i].fUsed = (((ShipmentPackageStruct)*spli).bItemQuality < 100); + + if(brps[i].fUsed) + { + for(j=0; j < MAXITEMS; j++) + { + if(LaptopSaveInfo.BobbyRayUsedInventory[j].usItemIndex == brps[i].usItemIndex) + { + break; + } + } + brps[i].usBobbyItemIndex = j; + } + else + { + for(j=0; j < MAXITEMS; j++) + { + if(LaptopSaveInfo.BobbyRayInventory[j].usItemIndex == brps[i].usItemIndex) + { + break; + } + } + brps[i].usBobbyItemIndex = j; + } + } + } + + /* if( giBobbyRShipmentSelectedShipment != -1 && gpNewBobbyrShipments[ giBobbyRShipmentSelectedShipment ].fActive && gpNewBobbyrShipments[ giBobbyRShipmentSelectedShipment ].fDisplayedInShipmentPage ) @@ -226,6 +294,18 @@ void RenderBobbyRShipments() // DisplayPurchasedItems( FALSE, BOBBYR_SHIPMENT_ORDER_GRID_X, BOBBYR_SHIPMENT_ORDER_GRID_Y, &LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray[giBobbyRShipmentSelectedShipment].BobbyRayPurchase[0], TRUE ); DisplayPurchasedItems( FALSE, BOBBYR_SHIPMENT_ORDER_GRID_X, BOBBYR_SHIPMENT_ORDER_GRID_Y, NULL, TRUE, giBobbyRShipmentSelectedShipment ); } + */ + + if( giBobbyRShipmentSelectedShipment != -1 && + gShipmentTable[ giBobbyRShipmentSelectedShipment ]->ShipmentStatus == SHIPMENT_INTRANSIT) // && + { + DisplayPurchasedItems( FALSE, BOBBYR_SHIPMENT_ORDER_GRID_X, BOBBYR_SHIPMENT_ORDER_GRID_Y,&brps[0], FALSE, giBobbyRShipmentSelectedShipment ); + } + else + { + DisplayPurchasedItems( FALSE, BOBBYR_SHIPMENT_ORDER_GRID_X, BOBBYR_SHIPMENT_ORDER_GRID_Y, NULL, TRUE, giBobbyRShipmentSelectedShipment ); + } + DisplayShipmentTitles(); DisplayPreviousShipments(); @@ -310,17 +390,27 @@ void DisplayPreviousShipments() UINT32 uiCnt; CHAR16 zText[512]; UINT16 usPosY = BOBBYR_SHIPMENT_ORDER_NUM_START_Y; - UINT32 uiNumItems = CountNumberValidShipmentForTheShipmentsPage(); + UINT32 uiNumItems; // = CountNumberValidShipmentForTheShipmentsPage(); UINT32 uiNumberItemsInShipments = 0; UINT32 uiItemCnt; UINT8 ubFontColor = BOBBYR_SHIPMENT_STATIC_TEXT_COLOR; + + RefToShipmentListIterator sli = gPostalService.LookupShipmentList().begin(); + + uiNumItems = (UINT32)gPostalService.LookupShipmentList().size(); + if(uiNumItems > BOBBYR_SHIPMENT_NUM_PREVIOUS_SHIPMENTS) + uiNumItems = BOBBYR_SHIPMENT_NUM_PREVIOUS_SHIPMENTS; //loop through all the shipments for( uiCnt=0; uiCntShipmentStatus == SHIPMENT_INTRANSIT) { if( uiCnt == (UINT32)giBobbyRShipmentSelectedShipment ) { @@ -332,17 +422,25 @@ void DisplayPreviousShipments() } //Display the "ordered on day num" - swprintf( zText, L"%s %d", gpGameClockString[0], gpNewBobbyrShipments[ uiCnt ].uiOrderedOnDayNum ); + //swprintf( zText, L"%s %d", gpGameClockString[0], gpNewBobbyrShipments[ uiCnt ].uiOrderedOnDayNum ); + swprintf( zText, L"%s %d", gpGameClockString[0], gShipmentTable[ uiCnt ]->uiOrderDate ); DrawTextToScreen( zText, BOBBYR_SHIPMENT_ORDER_NUM_X, usPosY, BOBBYR_SHIPMENT_ORDER_NUM_WIDTH, BOBBYR_SHIPMENT_STATIC_TEXT_FONT, ubFontColor, 0, FALSE, CENTER_JUSTIFIED ); uiNumberItemsInShipments = 0; + /* // for( uiItemCnt=0; uiItemCntShipmentPackages.size(); uiItemCnt++ ) + { + uiNumberItemsInShipments += gShipmentTable[ uiCnt ]->ShipmentPackages[uiItemCnt].ubNumber; + } + //Display the # of items swprintf( zText, L"%d", uiNumberItemsInShipments ); @@ -358,7 +456,8 @@ void CreatePreviousShipmentsMouseRegions() UINT16 usPosY = BOBBYR_SHIPMENT_ORDER_NUM_START_Y; UINT16 usWidth = BOBBYR_SHIPMENT_DELIVERY_GRID_WIDTH; UINT16 usHeight = GetFontHeight( BOBBYR_SHIPMENT_STATIC_TEXT_FONT ); - UINT32 uiNumItems = CountNumberOfBobbyPurchasesThatAreInTransit(); + //UINT32 uiNumItems = CountNumberOfBobbyPurchasesThatAreInTransit(); + UINT32 uiNumItems = gPostalService.GetShipmentCount(SHIPMENT_INTRANSIT); // WDS - If there are more than 13 shipments only show 13 because // that is all that will fit on the screen. If you show more things @@ -381,7 +480,8 @@ void CreatePreviousShipmentsMouseRegions() void RemovePreviousShipmentsMouseRegions() { UINT32 uiCnt; - UINT32 uiNumItems = CountNumberOfBobbyPurchasesThatAreInTransit(); + //UINT32 uiNumItems = CountNumberOfBobbyPurchasesThatAreInTransit(); + UINT32 uiNumItems = gPostalService.GetShipmentCount(SHIPMENT_INTRANSIT); for( uiCnt=0; uiCnt iSlotID ) +// if( CountNumberOfBobbyPurchasesThatAreInTransit() > iSlotID ) + if( gPostalService.GetShipmentCount(SHIPMENT_INTRANSIT) > iSlotID ) { INT32 iCnt; INT32 iValidShipmentCounter=0; @@ -408,9 +509,11 @@ void SelectPreviousShipmentsRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason giBobbyRShipmentSelectedShipment = -1; //loop through and get the "x" iSlotID shipment - for( iCnt=0; iCntShipmentStatus == SHIPMENT_INTRANSIT ) { if( iValidShipmentCounter == iSlotID ) { @@ -426,6 +529,9 @@ void SelectPreviousShipmentsRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason } } +//Dealtar's Airport Externalization +/* +* Function no longer used. INT32 CountNumberValidShipmentForTheShipmentsPage() { if( giNumberOfNewBobbyRShipment > BOBBYR_SHIPMENT_NUM_PREVIOUS_SHIPMENTS ) @@ -433,11 +539,5 @@ INT32 CountNumberValidShipmentForTheShipmentsPage() else return( giNumberOfNewBobbyRShipment ); } - - - - - - - +*/ diff --git a/Laptop/Laptop.vcproj b/Laptop/Laptop.vcproj index fae00d20..c2bc23ab 100644 --- a/Laptop/Laptop.vcproj +++ b/Laptop/Laptop.vcproj @@ -4491,6 +4491,9 @@ BrowseInformation="1"/> + + + + + + + + diff --git a/Laptop/Laptop_2005Express.vcproj b/Laptop/Laptop_2005Express.vcproj index 6ea35089..19272d06 100644 --- a/Laptop/Laptop_2005Express.vcproj +++ b/Laptop/Laptop_2005Express.vcproj @@ -512,6 +512,10 @@ RelativePath=".\personnel.h" > + + @@ -750,6 +754,10 @@ RelativePath=".\personnel.cpp" > + + @@ -758,6 +766,14 @@ RelativePath=".\Store Inventory.cpp" > + + + + diff --git a/Laptop/Laptop_VS2008.vcproj b/Laptop/Laptop_VS2008.vcproj index 4dd54c68..a11a56af 100644 --- a/Laptop/Laptop_VS2008.vcproj +++ b/Laptop/Laptop_VS2008.vcproj @@ -511,6 +511,10 @@ RelativePath="personnel.h" > + + @@ -751,6 +755,10 @@ RelativePath="personnel.cpp" > + + @@ -759,6 +767,14 @@ RelativePath="Store Inventory.cpp" > + + + + diff --git a/Laptop/PostalService.cpp b/Laptop/PostalService.cpp new file mode 100644 index 00000000..f4312755 --- /dev/null +++ b/Laptop/PostalService.cpp @@ -0,0 +1,730 @@ +#include "SaveLoadMap.h" +#include "Structure Wrap.h" +#include "Tactical Save.h" +#include "postalservice.h" +#include "strategic.h" +#include "strategicmap.h" +#include "random.h" +#include "game clock.h" +#include +#include +#include + +using namespace std; + +/************************************************************************************/ +/* New shipping system */ +/* =================== */ +/* */ +/* Old C-functions used: */ +/* - GridNoInVisibleWorldTile() */ +/* - SetOpenableStructureToClosed() */ +/* - ChangeStatusOfOpenableStructInUnloadedSector() */ +/* - CreateItem() */ +/* - CreateItems() */ +/* - AddItemToPool() */ +/* - AddItemsToUnLoadedSector() */ +/* - Random() */ +/* - AddFutureDayStrategicEvent() */ +/* */ +/* Old defines/macros: */ +/* - CALCULATE_STRATEGIC_INDEX() */ +/* - Assert() (for debugging) */ +/* */ +/* Old structs: */ +/* - OBJECTTYPE */ +/* */ +/* Old globals: */ +/* - StrategicMapElement StrategicMap[] */ +/************************************************************************************/ + +extern StrategicMapElement StrategicMap[]; + +///////////////////////////////////////////////////// +// CShipmentManipulator member implementation +///////////////////////////////////////////////////// +CShipmentManipulator::CShipmentManipulator(PCPostalService Owner, PShipmentStruct Shipment) +{ + this->_Shipment = Shipment; + this->_fContinueCallbackChain = TRUE; + this->_PostalService = Owner; +} + +INT16 CShipmentManipulator::GetSenderID(void) +{ + return _Shipment->sSenderID; +} + +RefToDestinationStruct CShipmentManipulator::GetDestination(void) const +{ + return *_Shipment->pDestination; +} + +void CShipmentManipulator::ContinueCallbackChain(BOOLEAN fContinue) +{ + _fContinueCallbackChain = fContinue; +} + +void CShipmentManipulator::CancelDelivery(void) +{ + _Shipment->ShipmentStatus = SHIPMENT_CANCEL_DELIVERY; +} + +////////////////////////////////////////// +// CPostalService member implementation +///////////////////////////////////////// + +DestinationList CPostalService::_Destinations; +vector CPostalService::_UsedDestinationIDList; +OBJECTTYPE CPostalService::tempObject; + +CPostalService::CPostalService() +{ +} + +UINT16 CPostalService::CreateNewShipment(UINT16 usDestinationID, UINT8 ubDeliveryMethodIndex, INT16 sSenderID) +{ + if( usDestinationID > _UsedDestinationIDList.size() || + !_UsedDestinationIDList[usDestinationID] || + ubDeliveryMethodIndex > _DeliveryMethods.size() ) + { + Assert(0); + return 0; + } + + _Destinations.sort(DESTINATION_LIST_ASCENDING); + RefToDestinationListIterator dli = _Destinations.begin(); + + while(DESTINATION(dli).usID != usDestinationID) + { + if(dli == _Destinations.end()) + { + Assert(0); + return 0; + } + dli++; + } + + UINT16 usNewID = 1; + if(_UsedShipmentIDList.empty()) + { + _UsedShipmentIDList.push_back(FALSE); + _UsedShipmentIDList.push_back(TRUE); + } + else + { + while(1) + { + if(usNewID == _UsedShipmentIDList.size() - 1) // All IDs assigned, add a new one + { + usNewID++; + _UsedShipmentIDList.push_back(TRUE); + break; + } + + if(!_UsedShipmentIDList[usNewID]) // Found an ID that is not assigned + { + _UsedShipmentIDList[usNewID] = TRUE; + break; + } + + usNewID++; + } + } + + ShipmentStruct shs; + shs.usID = usNewID; + shs.pDestination = &(DESTINATION(dli)); + shs.pDestinationDeliveryInfo = &(_DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(DESTINATION(dli).usID)); + shs.sSenderID = sSenderID; + shs.ShipmentStatus = SHIPMENT_STATIONARY; + shs.uiOrderDate = GetWorldDay(); + + _Shipments.push_back(shs); + + return usNewID; +} + +BOOLEAN CPostalService::AddPackageToShipment(UINT16 usShipmentID, UINT16 usItemIndex, UINT8 ubNumber, INT8 bItemQuality) +{ + if( usShipmentID > _UsedShipmentIDList.size() || + !_UsedShipmentIDList[usShipmentID]) + { + Assert(0); + return FALSE; + } + + _Shipments.sort(SHIPMENT_LIST_ASCENDING); + RefToShipmentListIterator sli = _Shipments.begin(); + + while(SHIPMENT(sli).usID != usShipmentID) + { + if(sli == _Shipments.end()) + { + Assert(0); + return FALSE; + } + sli++; + } + + ShipmentPackageStruct sps; + sps.usItemIndex = usItemIndex; + sps.ubNumber = ubNumber; + sps.bItemQuality = bItemQuality; + + SHIPMENT(sli).ShipmentPackages.push_back(sps); + + return TRUE; +} + +BOOLEAN CPostalService::SendShipment(UINT16 usShipmentID) +{ + if( usShipmentID > _UsedShipmentIDList.size() || + !_UsedShipmentIDList[usShipmentID]) + { + Assert(0); + return FALSE; + } + + RefToShipmentListIterator sli = _Shipments.begin(); + + while(SHIPMENT(sli).usID != usShipmentID) + { + if(sli == _Shipments.end()) + { + Assert(0); + return FALSE; + } + sli++; + } + + SHIPMENT(sli).ShipmentStatus = SHIPMENT_INTRANSIT; + + AddFutureDayStrategicEvent( EVENT_POSTAL_SERVICE_SHIPMENT, (8 + Random(4) ) * 60, usShipmentID, + SHIPMENT(sli).pDestinationDeliveryInfo->bDaysAhead); + return TRUE; +} + +BOOLEAN CPostalService::DeliverShipment(UINT16 usShipmentID) +{ + if( usShipmentID > _UsedShipmentIDList.size() || + !_UsedShipmentIDList[usShipmentID]) + { + Assert(0); + return FALSE; + } + + RefToShipmentListIterator sli = _Shipments.begin(); + + while(SHIPMENT(sli).usID != usShipmentID) + { + if(sli == _Shipments.end()) + { + Assert(0); + return FALSE; + } + sli++; + } + + if(SHIPMENT(sli).ShipmentStatus == SHIPMENT_STATIONARY) + { + return FALSE; + } + + PCShipmentManipulator ShipmentManipulator = new CShipmentManipulator(this, &SHIPMENT(sli)); + + // Delivery callback code goes here + if(_DeliveryCallbacks[0].DeliveryCallbackFunc) + { + _DeliveryCallbacks[0].DeliveryCallbackFunc(*ShipmentManipulator); + } + + if(ShipmentManipulator->_fContinueCallbackChain) + { + if( SHIPMENT(sli).sSenderID + 2 <= (INT16)_DeliveryCallbacks.size() && + _DeliveryCallbacks[SHIPMENT(sli).sSenderID + 1].DeliveryCallbackFunc) + { + _DeliveryCallbacks[SHIPMENT(sli).sSenderID + 1].DeliveryCallbackFunc(*ShipmentManipulator); + } + } + + + if(SHIPMENT(sli).ShipmentStatus == SHIPMENT_CANCEL_DELIVERY) + { + SHIPMENT(sli).ShipmentStatus = SHIPMENT_STATIONARY; + return FALSE; + } + + + RefToShipmentStruct shs = SHIPMENT(sli); + + if( StrategicMap[ CALCULATE_STRATEGIC_INDEX( shs.pDestination->ubMapX, shs.pDestination->ubMapY ) ].fEnemyControlled ) + { + return FALSE; + } + + if( (shs.pDestination->ubMapX > 0) && + (shs.pDestination->ubMapX < MAP_WORLD_X - 1) && + (shs.pDestination->ubMapY > 0) && + (shs.pDestination->ubMapY < MAP_WORLD_Y - 1) && + GridNoOnVisibleWorldTile(shs.pDestination->sGridNo) ) + { + BOOLEAN fSectorLoaded = ( gWorldSectorX == shs.pDestination->ubMapX ) && + ( gWorldSectorY == shs.pDestination->ubMapY ) && + ( gbWorldSectorZ == shs.pDestination->ubMapZ); + + if(fSectorLoaded) + { + SetOpenableStructureToClosed( shs.pDestination->sGridNo, 0 ); + } + else + { + ChangeStatusOfOpenableStructInUnloadedSector( shs.pDestination->ubMapX, shs.pDestination->ubMapY, + shs.pDestination->ubMapZ, shs.pDestination->sGridNo, FALSE ); + } + + UINT16 usNumberOfItems=0; + for(int i = 0; i < (int)shs.ShipmentPackages.size(); i++) + { + usNumberOfItems += shs.ShipmentPackages[i].ubNumber; + } + + OBJECTTYPE *pObject; + if(!fSectorLoaded) + { + pObject = new OBJECTTYPE[usNumberOfItems]; + + if(!pObject) + { + Assert(0); + return FALSE; + } + } + + UINT uiCount=0; + UINT8 ubItemsDelivered, ubTempNumItems; + UINT16 usItem; + + for(int i=0; i < (int)shs.ShipmentPackages.size(); i++) + { + ubItemsDelivered = shs.ShipmentPackages[i].ubNumber; + usItem = shs.ShipmentPackages[i].usItemIndex; + + CreateItem(usItem, 100, &tempObject); + + while ( ubItemsDelivered ) + { + //ubTempNumItems = __min( ubItemsDelivered, ItemSlotLimit(usItem, BIGPOCK1POS) ); + ubTempNumItems = __min( ubItemsDelivered, ItemSlotLimit(&tempObject, BIGPOCK1POS) ); + CreateItems( usItem, shs.ShipmentPackages[i].bItemQuality, ubTempNumItems, &tempObject ); + + if( fSectorLoaded ) + { + AddItemToPool( shs.pDestination->sGridNo, &tempObject, -1, 0, 0, 0 ); + } + else + { + pObject[ uiCount ] = tempObject; + uiCount++; + } + + ubItemsDelivered -= ubTempNumItems; + } + } + + if( !fSectorLoaded ) + { + if( !AddItemsToUnLoadedSector( shs.pDestination->ubMapX, shs.pDestination->ubMapY, + shs.pDestination->ubMapZ, shs.pDestination->sGridNo, uiCount, pObject, 0, 0, 0, -1, FALSE ) ) + { + Assert( 0 ); + } + delete[]( pObject ); + pObject = NULL; + } + + shs.ShipmentPackages.clear(); + shs.pDestination = NULL; + shs.pDestinationDeliveryInfo = NULL; + shs.ShipmentStatus = SHIPMENT_STATIONARY; + _UsedShipmentIDList[usShipmentID] = FALSE; + + _Shipments.erase(sli); + + return TRUE; + } + else + Assert(0); + + return FALSE; +} + +BOOLEAN CPostalService::RegisterDeliveryCallback(INT16 sSenderID, PtrToDeliveryCallbackFunc DeliveryCallbackFunc) +{ + if(sSenderID < - 1 || !DeliveryCallbackFunc) + { + Assert(0); + return 0; + } + + DeliveryCallbackDataStruct dcd; + + dcd.sSenderID=-1; + dcd.DeliveryCallbackFunc = NULL; + if(_DeliveryCallbacks.empty()) + { + _DeliveryCallbacks.push_back(dcd); + } + + if(sSenderID == -1) + { + dcd.DeliveryCallbackFunc = DeliveryCallbackFunc; + _DeliveryCallbacks[0].DeliveryCallbackFunc = DeliveryCallbackFunc; + } + else + { + // Note: For size comparsions, sSenderID has to be offset by 2, as index 0 of the callback vector is used by the default callback, + // taking up 1 element already + if(sSenderID + 2 > (INT16)_DeliveryCallbacks.size()) + { + _DeliveryCallbacks.resize(sSenderID+2); + _DeliveryCallbacks[sSenderID+1].DeliveryCallbackFunc = DeliveryCallbackFunc; + _DeliveryCallbacks[sSenderID+1].sSenderID = sSenderID; + } + else + { + _DeliveryCallbacks[sSenderID+1].sSenderID = sSenderID; + _DeliveryCallbacks[sSenderID+1].DeliveryCallbackFunc = DeliveryCallbackFunc; + } + } + + return TRUE; +} + +BOOLEAN CPostalService::LoadShipmentListFromSaveGameFile(HWFILE hFile) +{ + UINT32 uiBytesRead=0; + ShipmentListSaveFileDataHeaderStruct sls; + // Read in shipment list data header + + if(!_Shipments.empty()) + { + _Shipments.clear(); + } + + FileRead(hFile, &sls, sizeof(ShipmentListSaveFileDataHeaderStruct), &uiBytesRead); + if(uiBytesRead != sizeof(ShipmentListSaveFileDataHeaderStruct)) + { + return FALSE; + } + + ShipmentSaveFileDataStruct sfs; + ShipmentPackageStruct sps; + ShipmentStruct shs; + + for(int i = 0; i < (int)sls.uiNumberOfShipments; i++) + { + // Read in shipment data header + memset(&sfs, 0, sizeof(ShipmentSaveFileDataStruct)); + uiBytesRead = 0; + FileRead(hFile, &sfs, sizeof(ShipmentSaveFileDataStruct), &uiBytesRead); + if(uiBytesRead != sizeof(ShipmentSaveFileDataStruct)) + { + return FALSE; + } + + // Add shipment + memset(&shs, 0, sizeof(ShipmentStruct)); + shs.pDestination = &(_GetDestination(sfs.usDestinationID)); + shs.pDestinationDeliveryInfo = &(_DeliveryMethods[sfs.ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(sfs.usDestinationID)); + shs.ShipmentStatus = sfs.ShipmentStatus; + shs.sReceiverID = sfs.sReceiverID; + shs.sSenderID = sfs.sSenderID; + shs.usID = sfs.usID; + shs.uiOrderDate = sfs.uiOrderDate; + + _UsedShipmentIDList.resize(sfs.usID+1); + _UsedShipmentIDList[sfs.usID] = TRUE; + + for(int j=0; j < (int)sfs.uiNumberOfPackages; j++) + { + uiBytesRead=0; + memset(&sps, 0, sizeof(ShipmentPackageStruct)); + FileRead(hFile, &sps, sizeof(ShipmentPackageStruct), &uiBytesRead); + if(uiBytesRead != sizeof(ShipmentPackageStruct)) + { + return FALSE; + } + shs.ShipmentPackages.push_back(sps); + } + _Shipments.push_back(shs); + } + + return TRUE; +} + +BOOLEAN CPostalService::SaveShipmentListToSaveGameFile(HWFILE hFile) +{ + ShipmentListSaveFileDataHeaderStruct sls; + + sls.uiNumberOfShipments = _Shipments.size(); + sls.uiPackageDataSize = sizeof(ShipmentPackageStruct); + sls.uiShipmentDataSize = sizeof(ShipmentSaveFileDataStruct); + + UINT32 uiBytesWritten=0; + FileWrite(hFile, &sls, sizeof(ShipmentListSaveFileDataHeaderStruct), &uiBytesWritten); + if(uiBytesWritten != sizeof(ShipmentListSaveFileDataHeaderStruct)) + { + return FALSE; + } + + if(_Shipments.empty()) + { + return TRUE; + } + + RefToShipmentListIterator sli = _Shipments.begin(); + ShipmentSaveFileDataStruct sfs; + ShipmentPackageStruct sps; + + while(sli != _Shipments.end() ) + { + memset(&sfs, 0, sizeof(ShipmentSaveFileDataStruct)); + uiBytesWritten = 0; + + sfs.ShipmentStatus = SHIPMENT(sli).ShipmentStatus; + sfs.sReceiverID = SHIPMENT(sli).sReceiverID; + sfs.sSenderID = SHIPMENT(sli).sSenderID; + sfs.ubDeliveryMethodIndex = SHIPMENT(sli).pDestinationDeliveryInfo->ubParentDeliveryMethodIndex;; + sfs.uiNumberOfPackages = SHIPMENT(sli).ShipmentPackages.size(); + sfs.usDestinationID = SHIPMENT(sli).pDestination->usID; + sfs.usID = SHIPMENT(sli).usID; + sfs.uiOrderDate = SHIPMENT(sli).uiOrderDate; + + FileWrite(hFile, &sfs, sizeof(ShipmentSaveFileDataStruct), &uiBytesWritten); + if(uiBytesWritten != sizeof(ShipmentSaveFileDataStruct)) + { + return FALSE; + } + + for(int i = 0; i < (int)SHIPMENT(sli).ShipmentPackages.size(); i++) + { + memset(&sps, 0, sizeof(ShipmentPackageStruct)); + uiBytesWritten = 0; + + sps.bItemQuality = SHIPMENT(sli).ShipmentPackages[i].bItemQuality; + sps.ubNumber = SHIPMENT(sli).ShipmentPackages[i].ubNumber; + sps.usItemIndex = SHIPMENT(sli).ShipmentPackages[i].usItemIndex; + FileWrite(hFile, &sps, sizeof(ShipmentPackageStruct), &uiBytesWritten); + if(uiBytesWritten != sizeof(ShipmentPackageStruct)) + { + return FALSE; + } + } + + sli++; + } + + return TRUE; +} + +UINT16 CPostalService::AddDestination(UINT32 uiIndex, UINT8 ubMapX, UINT8 ubMapY, UINT8 ubMapZ, INT16 sGridNo, STR16 pszName) +{ + UINT16 usNewID=1; + // We need to find an ID first + if(_UsedDestinationIDList.empty()) // No IDs assigned yet + { + _UsedDestinationIDList.push_back(FALSE); // We're not using ID 0 to avoid confusion + _UsedDestinationIDList.push_back(TRUE); // This is the very first Destination so we use ID 1 + } + else // There are IDs assigned, let's see if there are any gaps + { + while(1) + { + if(usNewID == _UsedDestinationIDList.size() - 1) // All IDs assigned, add a new one + { + usNewID++; + _UsedDestinationIDList.push_back(TRUE); + break; + } + + if(!_UsedDestinationIDList[usNewID]) // Found an ID that is not assigned + { + _UsedDestinationIDList[usNewID] = TRUE; + break; + } + + usNewID++; + } + } + + // Alright, we've found a suitable ID, let's add the destination + DestinationStruct newDestination; + + newDestination.sGridNo = sGridNo; + newDestination.wstrName = pszName; + newDestination.uiIndex = uiIndex; + newDestination.ubMapX = ubMapX; + newDestination.ubMapY = ubMapY; + newDestination.ubMapZ = ubMapZ; + newDestination.usID = usNewID; + + _Destinations.push_back(newDestination); + + return usNewID; +} + +RefToDestinationList CPostalService::LookupDestinationList(void) const +{ + return _Destinations; +} + +UINT16 CPostalService::RemoveDestination(UINT16 usDestinationID) +{ + if( _Destinations.empty() || usDestinationID >= _UsedDestinationIDList.size() || _UsedDestinationIDList[usDestinationID] == FALSE ) + { + // ID is not in use or unknown or the list is actually empty + Assert(0); + return 0; + } + // ID is known and in use + _Destinations.sort(DESTINATION_LIST_ASCENDING); + DestinationList::iterator dli = _Destinations.begin(); + + while( ( (RefToDestinationStruct)*dli ).usID != usDestinationID ) + dli++; + + _Destinations.erase(dli); + _UsedDestinationIDList[usDestinationID] = FALSE; + + // TO-DO: Add some lines to check and clean up the used destination ID list, i.e. remove empty elements at the end of the list + + return usDestinationID; +} + +UINT16 CPostalService::GetShipmentCount(SHIPMENT_STATUS TargetedShipmentStatus) +{ + if(_Shipments.empty()) + { + return 0; + } + + RefToShipmentListIterator sli = _Shipments.begin(); + + UINT16 usCnt=0; + while(sli != _Shipments.end()) + { + usCnt += (SHIPMENT(sli).ShipmentStatus == TargetedShipmentStatus); + sli++; + } + return usCnt; +} + +RefToShipmentList CPostalService::LookupShipmentList(void) const +{ + return (RefToShipmentList)_Shipments; +} + +RefToDestinationStruct CPostalService::GetDestination(UINT16 usDestinationID) const +{ + if( usDestinationID > _UsedDestinationIDList.size() || + !_UsedDestinationIDList[usDestinationID]) + { + Assert(0); + return DESTINATION(_Destinations.end()); + } + + DestinationList::const_iterator dli = _Destinations.begin(); + + while(DESTINATION(dli).usID != usDestinationID) + { + if(dli == _Destinations.end()) + { + Assert(0); + return DESTINATION(_Destinations.end()); + } + dli++; + } + + return DESTINATION(dli); +} + +UINT8 CPostalService::AddDeliveryMethod(STR16 pszDescription) +{ + DeliveryMethodStruct dms; + + dms.wstrDescription = pszDescription; + dms.pDestinationDeliveryInfos = new DestinationDeliveryInfoTable; + + _DeliveryMethods.push_back(dms); + + return _DeliveryMethods.size() - 1; +} + +UINT16 CPostalService::SetDestinationDeliveryInfo(UINT8 ubDeliveryMethodIndex, UINT32 uiDestinationIndex, UINT16 usDestinationFee, INT8 bDaysAhead) +{ + if( (ubDeliveryMethodIndex > _DeliveryMethods.size() - 1) ) + { + Assert(0); + return 0; + } + + _DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->resize(_UsedDestinationIDList.size()); + + _Destinations.sort(DESTINATION_LIST_ASCENDING); + + RefToDestinationListIterator dli = _Destinations.begin(); + + while( DESTINATION(dli).uiIndex != uiDestinationIndex) + { + if(dli == _Destinations.end() ) + { + Assert(0); + return 0; // No destination with the specified index found + } + dli++; + } + + _DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(DESTINATION(dli).usID).ubParentDeliveryMethodIndex = ubDeliveryMethodIndex; + _DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(DESTINATION(dli).usID).usDestinationFee = usDestinationFee; + _DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(DESTINATION(dli).usID).bDaysAhead = bDaysAhead; + + return uiDestinationIndex; +} + +UINT16 CPostalService::GetDestinationFee(UINT8 ubDeliveryMethodIndex, UINT16 usDestinationID) +{ + if(_UsedDestinationIDList.empty() || + usDestinationID > _UsedDestinationIDList.size() || + !_UsedDestinationIDList[usDestinationID]) + { + Assert(0); + return 0; + } + + return _DeliveryMethods[ubDeliveryMethodIndex].pDestinationDeliveryInfos->at(usDestinationID).usDestinationFee; +} + +RefToDestinationStruct CPostalService::_GetDestination(UINT16 usDestinationID) +{ + if( usDestinationID > _UsedDestinationIDList.size() || + !_UsedDestinationIDList[usDestinationID]) + { + Assert(0); + return DESTINATION(_Destinations.end()); + } + + RefToDestinationListIterator dli = _Destinations.begin(); + + while(DESTINATION(dli).usID != usDestinationID) + { + if(dli == _Destinations.end()) + { + Assert(0); + return DESTINATION(_Destinations.end()); + } + dli++; + } + + return DESTINATION(dli); +} \ No newline at end of file diff --git a/Laptop/PostalService.h b/Laptop/PostalService.h new file mode 100644 index 00000000..27779a28 --- /dev/null +++ b/Laptop/PostalService.h @@ -0,0 +1,252 @@ +#ifndef __POSTAL_SERVICE_H +#define __POSTAL_SERVICE_H + +#include "SaveLoadMap.h" +#include "Structure Wrap.h" +#include "Tactical Save.h" +#include "laptopsave.h" +#include "postalservice.h" +#include "isometric utils.h" +#include "debug.h" +#include "game event hook.h" +#include "game events.h" +#include +#include +#include + +using namespace std; + +#define MAX_DEST_NAME_LENGTH 32 +#define MAX_DELIVERYMETHOD_DESC_LENGTH 32 +#define MAX_DESTINATIONS 255 +#define MAX_SHIPMENTS 255 + +////////////////////////////////////////////// + +class CPostalService; +typedef CPostalService& RefToCPostalService; +typedef CPostalService* PCPostalService; + +////////////////////////////////////////////// + +typedef struct +{ + UINT16 usID; + UINT32 uiIndex; // uiIndex is used as an ID number in external game data + UINT8 ubMapY; + UINT8 ubMapX; + UINT8 ubMapZ; + INT16 sGridNo; + wstring wstrName; +} DestinationStruct; + +typedef DestinationStruct& RefToDestinationStruct; +typedef DestinationStruct* PDestinationStruct; + +typedef list DestinationList; +typedef list& RefToDestinationList; +typedef DestinationList::const_iterator& RefToDestinationListIterator; +inline RefToDestinationStruct DESTINATION(RefToDestinationListIterator dli) +{ + return ( (RefToDestinationStruct) *dli ); +} + +inline BOOLEAN DESTINATION_ID_GREATER(RefToDestinationStruct d1, RefToDestinationStruct d2) +{ + return (d1.usID > d2.usID); +} +#define DESTINATION_LIST_DESCENDING DESTINATION_ID_GREATER + +inline BOOLEAN DESTINATION_ID_LOWER(RefToDestinationStruct d1, RefToDestinationStruct d2) +{ + return (d1.usID < d2.usID); +} +#define DESTINATION_LIST_ASCENDING DESTINATION_ID_LOWER + +inline BOOLEAN DESTINATION_ID_EQUAL(RefToDestinationStruct d1, RefToDestinationStruct d2) +{ + return (d1.usID == d2.usID); +} + +////////////////////////////////////////////////////////////// +typedef struct +{ + UINT8 ubParentDeliveryMethodIndex; + UINT16 usDestinationFee; + INT8 bDaysAhead; +}DestinationDeliveryInfoStruct; +typedef DestinationDeliveryInfoStruct& RefToDestinationDeliveryInfoStruct; +typedef DestinationDeliveryInfoStruct* PDestinationDeliveryInfoStruct; +typedef vector DestinationDeliveryInfoTable; +typedef DestinationDeliveryInfoTable* PDestinationDeliveryInfoTable; +typedef DestinationDeliveryInfoTable& RefToDestinationDeliveryInfoTable; +typedef DestinationDeliveryInfoTable::iterator DestinationDeliveryInfoTableIterator; +typedef DestinationDeliveryInfoTableIterator& RefToDestinationDeliveryInfoTableIterator; + +typedef struct +{ + wstring wstrDescription; + PDestinationDeliveryInfoTable pDestinationDeliveryInfos; +} DeliveryMethodStruct; +typedef DeliveryMethodStruct& RefToDeliveryMethodStruct; +typedef DeliveryMethodStruct* PDeliveryMethodStruct; +typedef vector DeliveryMethodTable; +typedef DeliveryMethodTable& RefToDeliveryMethodTable; + +///////////////////////////////////////////////////////////// +typedef struct +{ + UINT16 usItemIndex; + UINT8 ubNumber; + INT8 bItemQuality; +} ShipmentPackageStruct; +typedef ShipmentPackageStruct& RefToShipmentPackageStruct; +typedef ShipmentPackageStruct* PShipmentPackageStruct; +typedef vector ShipmentPackageList; +typedef ShipmentPackageList& RefToShipmentPackageList; +typedef ShipmentPackageList::iterator& RefToShipmentPackageListIterator; + +typedef enum +{ + SHIPMENT_STATIONARY=0, + SHIPMENT_INTRANSIT, + SHIPMENT_CANCEL_DELIVERY +} SHIPMENT_STATUS; + +typedef struct +{ + UINT16 usID; + SHIPMENT_STATUS ShipmentStatus; + ShipmentPackageList ShipmentPackages; + PDestinationStruct pDestination; + PDestinationDeliveryInfoStruct pDestinationDeliveryInfo; + INT16 sSenderID; // For now, two senders exist: Bobby Ray(0) and John Kulba(1) + INT16 sReceiverID; // Unused for now, but reserved for future projects + UINT32 uiOrderDate; +} ShipmentStruct; +typedef ShipmentStruct& RefToShipmentStruct; +typedef ShipmentStruct* PShipmentStruct; +typedef list ShipmentList; +typedef ShipmentList* PShipmentList; +typedef ShipmentList& RefToShipmentList; +typedef ShipmentList::iterator ShipmentListIterator; +typedef ShipmentListIterator& RefToShipmentListIterator; + +typedef struct +{ + UINT32 uiNumberOfShipments; + UINT32 uiShipmentDataSize; + UINT32 uiPackageDataSize; +}ShipmentListSaveFileDataHeaderStruct; +typedef ShipmentListSaveFileDataHeaderStruct* PShipmentListSaveFileDataHeaderStruct; + +typedef struct +{ + UINT16 usID; + SHIPMENT_STATUS ShipmentStatus; + UINT32 uiNumberOfPackages; + UINT16 usDestinationID; + UINT8 ubDeliveryMethodIndex; + INT16 sSenderID; + INT16 sReceiverID; + UINT32 uiOrderDate; +} ShipmentSaveFileDataStruct; +typedef ShipmentSaveFileDataStruct* PShipmentSaveFileDataStruct; + +inline BOOLEAN SHIPMENT_ID_LOWER(RefToShipmentStruct s1, RefToShipmentStruct s2) +{ + return (s1.usID < s2.usID); +} +#define SHIPMENT_LIST_ASCENDING SHIPMENT_ID_LOWER + +inline RefToShipmentStruct SHIPMENT(RefToShipmentListIterator sli) +{ + return ( (RefToShipmentStruct) *sli ); +} +//////////////////////////////////////////////////////////////// +class CShipmentManipulator +{ + friend CPostalService; +public: + INT16 GetSenderID(void); + RefToDestinationStruct GetDestination(void) const; + void ContinueCallbackChain(BOOLEAN fContinue); + void CancelDelivery(void); + CShipmentManipulator(PCPostalService Owner, PShipmentStruct Shipment); +private: + PCPostalService _PostalService; + PShipmentStruct _Shipment; + BOOLEAN _fContinueCallbackChain; +}; +typedef CShipmentManipulator& RefToCShipmentManipulator; +typedef CShipmentManipulator* PCShipmentManipulator; + +typedef void (*PtrToDeliveryCallbackFunc)(RefToCShipmentManipulator ShipmentManipulator); + +typedef struct +{ + INT16 sSenderID; + PtrToDeliveryCallbackFunc DeliveryCallbackFunc; +} DeliveryCallbackDataStruct; +typedef DeliveryCallbackDataStruct& RefToDeliveryCallbackDataStruct; +typedef vector DeliveryCallbackDataList; +typedef DeliveryCallbackDataList& RefToDeliveryCallbackDataList; +typedef DeliveryCallbackDataList::iterator DeliveryCallbackDataListIterator; +typedef DeliveryCallbackDataListIterator& RefToDeliveryCallbackDataListIterator; + +//////////////////////////////////////////////////////////////// +class CPostalService +{ + friend BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ); + friend CShipmentManipulator; +public: + // Shipment management + UINT16 CreateNewShipment(UINT16 usDestinationID, UINT8 ubDeliveryMethodIndex, INT16 sSenderID); + BOOLEAN AddPackageToShipment(UINT16 usShipmentID, UINT16 usItemIndex, UINT8 ubNumber, INT8 bItemQuality); + BOOLEAN SendShipment(UINT16 usShipmentID); + BOOLEAN DeliverShipment(UINT16 usShipmentID); + BOOLEAN RegisterDeliveryCallback(INT16 sSenderID, PtrToDeliveryCallbackFunc DeliveryCallbackFunc); + + // Interfaces + BOOLEAN LoadShipmentListFromSaveGameFile(HWFILE hFile); + BOOLEAN SaveShipmentListToSaveGameFile(HWFILE hFile); + + // Shipment utility functions + UINT16 GetShipmentCount(SHIPMENT_STATUS TargetedShipmentStatus); + RefToShipmentList LookupShipmentList(void) const; + + + // Destination management + UINT16 AddDestination(UINT32 uiIndex, UINT8 ubMapX, UINT8 ubMapY, UINT8 ubMapZ, INT16 sGridNo, STR16 pszName ); + UINT16 RemoveDestination(UINT16 usDestinationID); + RefToDestinationStruct GetDestination(UINT16 usDestinationID) const; + RefToDestinationList LookupDestinationList(void) const; + + // Delivery method management + UINT8 AddDeliveryMethod(STR16 pszDescription); + UINT16 SetDestinationDeliveryInfo(UINT8 ubDeliveryMethodIndex, UINT32 uiDestinationIndex, UINT16 usDestinationFee, INT8 bDaysAhead); + UINT16 GetDestinationFee(UINT8 ubDeliveryMethodIndex, UINT16 usDestinationID); + RefToDeliveryMethodStruct GetDeliveryMethod(UINT8 ubDeliveryMethodIndex) const; + + CPostalService(); +private: + ShipmentList _Shipments; + vector _UsedShipmentIDList; + DeliveryCallbackDataList _DeliveryCallbacks; + static OBJECTTYPE tempObject; + + + // All instances share the same set of destinations... + static DestinationList _Destinations; + static vector _UsedDestinationIDList; + + RefToDestinationStruct _GetDestination(UINT16 usDestinationID); + + // ...but they may have different delivery methods available so these are managed individually + DeliveryMethodTable _DeliveryMethods; + + RefToDestinationDeliveryInfoStruct _GetDestinationDeliveryInfo(UINT8 ubDeliveryMethodIndex, UINT16 usDestinationID); +protected: +}; + +#endif \ No newline at end of file diff --git a/Laptop/XML_DeliveryMethods.cpp b/Laptop/XML_DeliveryMethods.cpp new file mode 100644 index 00000000..0f84661c --- /dev/null +++ b/Laptop/XML_DeliveryMethods.cpp @@ -0,0 +1,266 @@ +#include "sgp.h" +#include "overhead types.h" +#include "overhead.h" +#include "text.h" +#include "Debug Control.h" +#include "expat.h" +#include "XML.h" +#include "PostalService.h" +#include +#include + +using namespace std; + +extern CPostalService gPostalService; + +typedef struct +{ + UINT32 uiDestinationIndex; + UINT16 usDestinationFee; + INT8 bDaysAhead; +}DestinationDeliveryInfoReadInStruct; +typedef DestinationDeliveryInfoReadInStruct& RefToDestinationDeliveryInfoReadInStruct; +typedef vector DestinationDeliveryInfoReadInTable; +typedef DestinationDeliveryInfoReadInTable& RefToDestinationDeliveryInfoReadInTable; +typedef DestinationDeliveryInfoReadInTable::iterator DestinationDeliveryInfoReadInTableIterator; +typedef DestinationDeliveryInfoReadInTableIterator& RefToDestinationDeliveryInfoReadInTableIterator; + +enum +{ + DELIVERYMETHOD_ELEMENT_NONE=0, + DELIVERYMETHOD_ELEMENT_TABLE, + DELIVERYMETHOD_ELEMENT, + DELIVERYMETHOD_ELEMENT_PROPERTY, + DESTINATIONDELIVERYINFO_ELEMENT_TABLE, + DESTINATIONDELIVERYINFO_ELEMENT, + DESTINATIONDELIVERYINFO_ELEMENT_PROPERTY +}typedef DELIVERYMETHOD_PARSE_STAGE; + +struct +{ + DELIVERYMETHOD_PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + + struct + { + CHAR16 szDescription[MAX_DELIVERYMETHOD_DESC_LENGTH+1]; + DestinationDeliveryInfoReadInTable DestinationDeliveryInfos; + }CurDeliveryMethod; + + struct + { + UINT32 uiDestinationIndex; + UINT16 usDestinationFee; + INT8 bDaysAhead; + }CurDestinationDeliveryInfo; + + UINT32 maxArraySize; + UINT32 currentDepth; + UINT32 maxReadDepth; +} +typedef deliveryMethodParseData; + +static void XMLCALL +deliveryMethodStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) +{ + deliveryMethodParseData * pData = (deliveryMethodParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "DELIVERYMETHODTABLE") == 0 && pData->curElement == DELIVERYMETHOD_ELEMENT_NONE) + { + pData->curElement = DELIVERYMETHOD_ELEMENT_TABLE; + + pData->maxReadDepth++; + } + else if(strcmp(name, "DELIVERYMETHOD") == 0 && pData->curElement == DELIVERYMETHOD_ELEMENT_TABLE) + { + pData->curElement = DELIVERYMETHOD_ELEMENT; + pData->maxReadDepth++; + } + else if(pData->curElement == DELIVERYMETHOD_ELEMENT && + (strcmp(name, "description") == 0) ) + { + pData->curElement = DELIVERYMETHOD_ELEMENT_PROPERTY; + + pData->maxReadDepth++; + } + else if(pData->curElement == DELIVERYMETHOD_ELEMENT && + (strcmp(name, "DESTINATIONDELIVERYINFOTABLE") == 0)) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT_TABLE; + + pData->maxReadDepth++; + } + else if(pData->curElement == DESTINATIONDELIVERYINFO_ELEMENT_TABLE && + (strcmp(name, "DESTINATIONDELIVERYINFO") == 0)) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT; + + pData->maxReadDepth++; + } + else if(pData->curElement == DESTINATIONDELIVERYINFO_ELEMENT && + (strcmp(name, "uiDestinationIndex") == 0 || + strcmp(name, "usDestinationFee") == 0 || + strcmp(name, "bDaysAhead") == 0 ) ) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT_PROPERTY; + + pData->maxReadDepth++; + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +deliveryMethodCharacterDataHandle(void *userData, const XML_Char *str, int len) +{ + deliveryMethodParseData * pData = (deliveryMethodParseData *)userData; + + if( (pData->currentDepth <= pData->maxReadDepth) && + (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + ){ + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); + } +} + +static void XMLCALL +deliveryMethodEndElementHandle(void *userData, const XML_Char *name) +{ + deliveryMethodParseData * pData = (deliveryMethodParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "DELIVERYMETHODTABLE") == 0) + { + pData->curElement = DELIVERYMETHOD_ELEMENT_NONE; + } + else if(strcmp(name, "DELIVERYMETHOD") == 0) + { + pData->curElement = DELIVERYMETHOD_ELEMENT_TABLE; + UINT8 ubCurrentDM = gPostalService.AddDeliveryMethod(pData->CurDeliveryMethod.szDescription); + + RefToDestinationDeliveryInfoReadInTableIterator dfriti = pData->CurDeliveryMethod.DestinationDeliveryInfos.begin(); + + while(dfriti != pData->CurDeliveryMethod.DestinationDeliveryInfos.end()) + { + gPostalService.SetDestinationDeliveryInfo(ubCurrentDM, ((RefToDestinationDeliveryInfoReadInStruct)*dfriti).uiDestinationIndex, ((RefToDestinationDeliveryInfoReadInStruct)*dfriti).usDestinationFee, ((RefToDestinationDeliveryInfoReadInStruct)*dfriti).bDaysAhead); + dfriti++; + } + + // Clean up + pData->CurDeliveryMethod.DestinationDeliveryInfos.clear(); + memset(pData->CurDeliveryMethod.szDescription, 0, sizeof(pData->CurDeliveryMethod.szDescription)); + pData->CurDestinationDeliveryInfo.uiDestinationIndex = 0; + pData->CurDestinationDeliveryInfo.uiDestinationIndex = 0; + } + else if(strcmp(name, "description") == 0) + { + pData->curElement = DELIVERYMETHOD_ELEMENT; + MultiByteToWideChar(CP_UTF8, 0, pData->szCharData, -1, &pData->CurDeliveryMethod.szDescription[0], MAX_DELIVERYMETHOD_DESC_LENGTH); + } + else if(strcmp(name, "DESTINATIONDELIVERYINFOTABLE") == 0) + { + pData->curElement = DELIVERYMETHOD_ELEMENT; + } + else if(strcmp(name, "DESTINATIONDELIVERYINFO") == 0) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT_TABLE; + DestinationDeliveryInfoReadInStruct dfris; + + dfris.uiDestinationIndex = pData->CurDestinationDeliveryInfo.uiDestinationIndex; + dfris.usDestinationFee = pData->CurDestinationDeliveryInfo.usDestinationFee; + dfris.bDaysAhead = pData->CurDestinationDeliveryInfo.bDaysAhead; + + memset(&pData->CurDestinationDeliveryInfo, 0, sizeof(pData->CurDestinationDeliveryInfo)); + + pData->CurDeliveryMethod.DestinationDeliveryInfos.push_back(dfris); + } + else if(strcmp(name, "uiDestinationIndex") == 0) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT; + pData->CurDestinationDeliveryInfo.uiDestinationIndex = strtoul(pData->szCharData, NULL, 10); + } + else if(strcmp(name, "usDestinationFee") == 0) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT; + pData->CurDestinationDeliveryInfo.usDestinationFee = (UINT16) strtoul(pData->szCharData, NULL, 10); + } + else if(strcmp(name, "bDaysAhead") == 0) + { + pData->curElement = DESTINATIONDELIVERYINFO_ELEMENT; + pData->CurDestinationDeliveryInfo.bDaysAhead = (INT8) strtoul(pData->szCharData, NULL, 10); + } + + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + +BOOLEAN ReadInDeliveryMethods(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + deliveryMethodParseData pData; + + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading DeliveryMethods.xml" ); + + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; + + FileClose( hFile ); + + + XML_SetElementHandler(parser, deliveryMethodStartElementHandle, deliveryMethodEndElementHandle); + XML_SetCharacterDataHandler(parser, deliveryMethodCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + pData.maxArraySize = sizeof(UINT16); + + XML_SetUserData(parser, &pData); + + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in DeliveryMethods.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + + XML_ParserFree(parser); + + // Interface stuff for the old game code. Once Bobby Ray and the laptop are fully C++'ized and/or externalised, this stuff can go + + + return( TRUE ); +} \ No newline at end of file diff --git a/Laptop/XML_ShippingDestinations.cpp b/Laptop/XML_ShippingDestinations.cpp new file mode 100644 index 00000000..73b6d3b2 --- /dev/null +++ b/Laptop/XML_ShippingDestinations.cpp @@ -0,0 +1,203 @@ +#include "sgp.h" +#include "overhead types.h" +#include "overhead.h" +#include "text.h" +#include "Debug Control.h" +#include "expat.h" +#include "XML.h" +#include "PostalService.h" +#include +#include + +using namespace std; + +CPostalService gPostalService; + +typedef struct +{ + UINT8 ubMapY; + UINT8 ubMapX; + UINT8 ubMapZ; + UINT32 uiIndex; + INT16 sGridNo; + CHAR16 szName[MAX_DEST_NAME_LENGTH+1]; +} DestinationReadInStruct; + +struct +{ + PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + + DestinationReadInStruct tempDest; + UINT32 maxArraySize; + UINT32 curIndex; + UINT32 currentDepth; + UINT32 maxReadDepth; +} +typedef destinationParseData; + +static void XMLCALL +destinationStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) +{ + destinationParseData * pData = (destinationParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "DESTINATIONLIST") == 0 && pData->curElement == ELEMENT_NONE) + { + pData->curElement = ELEMENT_LIST; + + pData->maxReadDepth++; + } + else if(strcmp(name, "DESTINATION") == 0 && pData->curElement == ELEMENT_LIST) + { + pData->curElement = ELEMENT; + memset(&pData->tempDest, 0, sizeof(DestinationReadInStruct)); + pData->maxReadDepth++; + pData->curIndex++; + } + else if(pData->curElement == ELEMENT && + (strcmp(name, "name") == 0 || + strcmp(name, "ubMapX") == 0 || + strcmp(name, "ubMapY") == 0 || + strcmp(name, "ubMapZ") == 0 || + strcmp(name, "sGridNo") == 0 || + strcmp(name, "uiIndex") == 0)) + { + pData->curElement = ELEMENT_PROPERTY; + + pData->maxReadDepth++; + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +destinationCharacterDataHandle(void *userData, const XML_Char *str, int len) +{ + destinationParseData * pData = (destinationParseData *)userData; + + if( (pData->currentDepth <= pData->maxReadDepth) && + (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + ){ + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); + } +} + +static void XMLCALL +destinationEndElementHandle(void *userData, const XML_Char *name) +{ + destinationParseData * pData = (destinationParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "DESTINATIONLIST") == 0) + { + pData->curElement = ELEMENT_NONE; + } + else if(strcmp(name, "DESTINATION") == 0) + { + pData->curElement = ELEMENT_LIST; + + gPostalService.AddDestination(pData->tempDest.uiIndex, pData->tempDest.ubMapX, pData->tempDest.ubMapY, pData->tempDest.ubMapZ, pData->tempDest.sGridNo, pData->tempDest.szName); + } + else if(strcmp(name, "name") == 0) + { + pData->curElement = ELEMENT; + MultiByteToWideChar(CP_UTF8, 0, pData->szCharData, -1, pData->tempDest.szName, MAX_DEST_NAME_LENGTH); + + } + else if(strcmp(name, "ubMapX") == 0) + { + pData->curElement = ELEMENT; + pData->tempDest.ubMapX = (UINT8)strtoul(pData->szCharData, NULL, 10); + } + else if(strcmp(name, "ubMapY") == 0) + { + pData->curElement = ELEMENT; + pData->tempDest.ubMapY = (UINT8)strtoul(pData->szCharData, NULL, 10); + + } + else if(strcmp(name, "ubMapZ") == 0) + { + pData->curElement = ELEMENT; + pData->tempDest.ubMapZ = (UINT8)strtoul(pData->szCharData, NULL, 10); + } + else if(strcmp(name, "sGridNo") == 0) + { + pData->curElement = ELEMENT; + pData->tempDest.sGridNo = (UINT16) atoi(pData->szCharData); + } + else if(strcmp(name, "uiIndex") == 0) + { + pData->curElement = ELEMENT; + pData->tempDest.uiIndex = (UINT8)strtoul(pData->szCharData, NULL, 10); + } + + + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + +BOOLEAN ReadInShippingDestinations(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + destinationParseData pData; + + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading ShippingDestinations.xml" ); + + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; + + FileClose( hFile ); + + XML_SetElementHandler(parser, destinationStartElementHandle, destinationEndElementHandle); + XML_SetCharacterDataHandler(parser, destinationCharacterDataHandle); + + memset(&pData,0,sizeof(pData)); + pData.maxArraySize = sizeof(UINT16); + pData.curIndex = -1; + + XML_SetUserData(parser, &pData); + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in ShippingDestinations.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + XML_ParserFree(parser); + + return( TRUE ); +} \ No newline at end of file diff --git a/Laptop/email.cpp b/Laptop/email.cpp index 42fc1db2..9c0f65ac 100644 --- a/Laptop/email.cpp +++ b/Laptop/email.cpp @@ -21,8 +21,12 @@ #include "Text.h" #include "LaptopSave.h" #include "finances.h" + #include "PostalService.h" + #include #endif +using namespace std; + //static EmailPtr pEmailList; EmailPtr pEmailList; static PagePtr pPageList; @@ -324,6 +328,8 @@ void PreProcessEmail( EmailPtr pMail ); void ModifyInsuranceEmails( UINT16 usMessageId, INT32 *iResults, EmailPtr pMail, UINT8 ubNumberOfRecords ); BOOLEAN ReplaceMercNameAndAmountWithProperData( CHAR16 *pFinishedString, EmailPtr pMail ); BOOLEAN ReplaceBiffNameWithProperMercName( CHAR16 *pFinishedString, EmailPtr pMail, CHAR16 *pMercName ); +extern UINT16 gusCurShipmentDestinationID; +extern CPostalService gPostalService; void InitializeMouseRegions() @@ -3174,6 +3180,36 @@ BOOLEAN HandleMailSpecialMessages( UINT16 usMessageId, INT32 *iResults, EmailPtr case AIM_MEDICAL_DEPOSIT_PARTIAL_REFUND: ModifyInsuranceEmails( usMessageId, iResults, pMail, AIM_MEDICAL_DEPOSIT_REFUND_LENGTH ); break; + //Dealtar's Airport Externalization + case BOBBYR_SHIPMENT_ARRIVED: + wstring wstrMail; + wstring::size_type index; + CHAR16 szMail[MAIL_STRING_SIZE]; + + if (!pMessageRecordList) + { + for (int i = 0; i < BOBBYR_SHIPMENT_ARRIVED_LENGTH; i++) + { + wstrMail.clear(); + LoadEncryptedDataFromFile("BINARYDATA\\Email.edt", szMail, MAIL_STRING_SIZE *usMessageId, MAIL_STRING_SIZE); + wstrMail = szMail; + + index = wstrMail.find(L"$DESTINATIONNAME$"); + + if (index != wstring::npos) + { + wstrMail.erase(index, strlen("$DESTINATIONNAME$")); + RefToDestinationStruct ds = gPostalService.GetDestination(gusCurShipmentDestinationID); + wstrMail.insert(index, ds.wstrName.c_str()); + } + + AddEmailRecordToList((STR16)wstrMail.c_str()); + + usMessageId++; + } + } + giPrevMessageId = giMessageId; + break; } return fSpecialCase; diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 9f3ab467..34b4ddcd 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -105,6 +105,7 @@ #include "Assignments.h" #include "Interface Items.h" #include "Shopkeeper Interface.h" + #include "postalservice.h" // HEADROCK HAM B1: Additional Include for HAM #include "MilitiaSquads.h" #endif @@ -142,6 +143,8 @@ extern void ResetJA2ClockGlobalTimers( void ); extern void BeginLoadScreen( void ); extern void EndLoadScreen(); +extern CPostalService gPostalService; + //Global variable used #ifdef JA2BETAVERSION UINT32 guiNumberOfMapTempFiles; //Test purposes @@ -2807,6 +2810,13 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) SaveGameFilePosition( FileGetPos( hFile ), "New way of saving Bobby R mailorders" ); #endif + // Dealtar: New shipment system data + if(!gPostalService.SaveShipmentListToSaveGameFile(hFile)) + { + ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing mail orders"); + goto FAILED_TO_SAVE; + } + //Close the saved game file @@ -4131,6 +4141,17 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) HandleOldBobbyRMailOrders(); } + //Dealtar's Airport Externalization + if( SaveGameHeader.uiSavedGameVersion >= 104 ) + { + if ( !gPostalService.LoadShipmentListFromSaveGameFile(hFile) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("gPostalService.LoadShipmentListFromSaveGameFile failed" ) ); + FileClose( hFile ); + return( FALSE ); + } + } + uiRelEndPerc += 1; SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." ); diff --git a/SaveLoadScreen.cpp b/SaveLoadScreen.cpp index 7d192ebc..f77f0448 100644 --- a/SaveLoadScreen.cpp +++ b/SaveLoadScreen.cpp @@ -36,6 +36,7 @@ #include "Map Screen Interface.h" #include "Multi Language Graphic Utils.h" #include "Campaign Types.h" + #include "PostalService.h" #endif #include "Campaign Init.h" @@ -201,6 +202,10 @@ BOOLEAN gfGettingNameFromSaveLoadScreen = FALSE; extern BOOLEAN gfDisplaySaveGamesNowInvalidatedMsg; #endif +//Dealtar's Airport Externalization +extern CPostalService gPostalService; + + // //Buttons // diff --git a/Strategic/Game Event Hook.cpp b/Strategic/Game Event Hook.cpp index 320dc5ec..e3afedb6 100644 --- a/Strategic/Game Event Hook.cpp +++ b/Strategic/Game Event Hook.cpp @@ -44,6 +44,7 @@ #include "Soldier Profile.h" #include "laptop.h" #include "Campaign.h" + #include "PostalService.h" #endif #include "connect.h" @@ -59,6 +60,7 @@ extern void HandleMinuteUpdate(); extern BOOLEAN gfProcessingGameEvents; extern UINT32 guiTimeStampOfCurrentlyExecutingEvent; extern BOOLEAN gfPreventDeletionOfAnyEvent; +extern CPostalService gPostalService; #ifdef CRIPPLED_VERSION @@ -433,6 +435,9 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent ) case EVENT_MERC_SITE_NEW_MERC_AVAILABLE: NewMercsAvailableAtMercSiteCallBack( ); break; + case EVENT_POSTAL_SERVICE_SHIPMENT: + gPostalService.DeliverShipment(pEvent->uiParam); + break; #ifdef CRIPPLED_VERSION case EVENT_CRIPPLED_VERSION_END_GAME_CHECK: diff --git a/Strategic/Game Event Hook.h b/Strategic/Game Event Hook.h index 1ee15559..34d56bef 100644 --- a/Strategic/Game Event Hook.h +++ b/Strategic/Game Event Hook.h @@ -83,6 +83,7 @@ enum EVENT_QUARTER_HOUR_UPDATE, EVENT_MERC_MERC_WENT_UP_LEVEL_EMAIL_DELAY, EVENT_MERC_SITE_NEW_MERC_AVAILABLE, + EVENT_POSTAL_SERVICE_SHIPMENT, // EVENT_CHECK_FOR_AIR_RAID, #ifdef CRIPPLED_VERSION diff --git a/Strategic/Game Events.cpp b/Strategic/Game Events.cpp index 4f77960f..79a44b71 100644 --- a/Strategic/Game Events.cpp +++ b/Strategic/Game Events.cpp @@ -102,6 +102,7 @@ CHAR16 gEventName[NUMBER_OF_EVENT_TYPES_PLUS_ONE][40]={ L"Rainstorm", L"Quarter Hour Update", L"MERC Merc went up level email delay", + L"CPostalService delivery", L".", #ifdef CRIPPLED_VERSION L"Crippled version end game check", diff --git a/Tactical/XML.h b/Tactical/XML.h index 23d3bc5b..e5ec6cf8 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -108,6 +108,9 @@ typedef PARSE_STAGE; // WANNE: Sector loadscreens [2007-05-18] #define SECTORLOADSCREENSFILENAME "Map\\SectorLoadscreens.xml" +// Dealtar: Shipping destinations and delivery methods +#define SHIPPINGDESTINATIONSFILENAME "Map\\ShippingDestinations.xml" +#define DELIVERYMETHODSFILENAME "Map\\DeliveryMethods.xml" // Gotthard: Laptop Text files [2007-10-16] #define LAPTOPFLORISTTEXTFILENAME "Laptop\\Florist.xml" #define LAPTOPFUNERALTEXTFILENAME "Laptop\\Funeral.xml" @@ -227,6 +230,9 @@ extern BOOLEAN WriteInArmyCompositionInfo(STR fileName); //Kaiden: Roaming Militia Restricted Sectors List extern BOOLEAN ReadInRoamingInfo(STR filename); +// Dealtar: New shipping system XMLs +extern BOOLEAN ReadInShippingDestinations(STR fileName); +extern BOOLEAN ReadInDeliveryMethods(STR fileName); //Gotthard: Laptop Florist Text extern BOOLEAN ReadInFloristText(STR fileName); diff --git a/ja2_2005Express.vcproj b/ja2_2005Express.vcproj index 5c64bfa7..db77fa4f 100644 --- a/ja2_2005Express.vcproj +++ b/ja2_2005Express.vcproj @@ -1,7 +1,7 @@