UINT8 GetNextAimAd( UINT8 ubCurrentAd ) { UINT8 ubNextAd; UINT32 uiDay = GetWorldDay(); BOOLEAN fSkip=FALSE; if( ubCurrentAd == AIM_AD_WARNING_BOX ) { if( uiDay <= AIM_AD_DAY_ADDVERTISMENT_FOR_ADS )//AIM_AD_BOBBYR_AD_STARTS ubNextAd = AIM_AD_FOR_ADS; else if( uiDay < AIM_AD_DAY_FUNERAL_AD_STARTS ) ubNextAd = AIM_AD_FUNERAL_ADS; else if( uiDay < AIM_AD_DAY_FLOWER_AD_STARTS ) ubNextAd = AIM_AD_FLOWER_SHOP; else //if( uiDay < AIM_AD_DAY_INSURANCE_AD_STARTS ) ubNextAd = AIM_AD_INSURANCE_AD; } else { ubNextAd = AIM_AD_WARNING_BOX; } return( ubNextAd ); }
UINT8 GetNextAimAd( UINT8 ubCurrentAd ) { UINT8 ubNextAd; UINT32 uiDay = GetWorldDay(); if( ubCurrentAd == AIM_AD_WARNING_BOX ) { if( uiDay < AIM_AD_BOBBYR_AD_STARTS ) { //if the player has NOT ever been to drassen if( !LaptopSaveInfo.fBobbyRSiteCanBeAccessed ) { ubNextAd = AIM_AD_FOR_ADS; } else { ubNextAd = AIM_AD_BOBBY_RAY_AD; } } else if( uiDay < AIM_AD_DAY_FUNERAL_AD_STARTS ) ubNextAd = AIM_AD_FUNERAL_ADS; else if( uiDay < AIM_AD_DAY_FLOWER_AD_STARTS ) ubNextAd = AIM_AD_FLOWER_SHOP; else //if( uiDay < AIM_AD_DAY_INSURANCE_AD_STARTS ) ubNextAd = AIM_AD_INSURANCE_AD; } else { ubNextAd = AIM_AD_WARNING_BOX; } return( ubNextAd ); }
BOOLEAN ContractIsExpiring( SOLDIERTYPE *pSoldier ) { UINT32 uiCheckHour; // First at least make sure same day.... if( ( pSoldier->iEndofContractTime /1440 ) <= (INT32)GetWorldDay( ) ) { uiCheckHour = GetHourWhenContractDone( pSoldier ); // See if the hour we are on is the same.... if ( GetWorldHour( ) == uiCheckHour ) { // All's good for go! return( TRUE ); } } return( FALSE ); }
BOOLEAN ContractIsGoingToExpireSoon( SOLDIERTYPE *pSoldier ) { // get hour contract is going to expire.... UINT32 uiCheckHour; // First at least make sure same day.... if( ( pSoldier->iEndofContractTime /1440 ) <= (INT32)GetWorldDay( ) ) { uiCheckHour = GetHourWhenContractDone( pSoldier ); // If we are <= 2 hours from expiry. if ( GetWorldHour( ) >= ( uiCheckHour - 2 ) ) { // All's good for go! return( TRUE ); } } return( FALSE ); }
// ALL changes of control to player must be funneled through here! BOOLEAN SetThisSectorAsPlayerControlled( INT16 sMapX, INT16 sMapY, INT8 bMapZ, BOOLEAN fContested ) { // NOTE: MapSector must be 16-bit, cause MAX_WORLD_X is actually 18, so the sector numbers exceed 256 although we use only 16x16 UINT16 usMapSector = 0; BOOLEAN fWasEnemyControlled = FALSE; INT8 bTownId = 0; UINT8 ubSectorID; if( AreInMeanwhile( ) ) { return FALSE; } if( bMapZ == 0 ) { usMapSector = sMapX + ( sMapY * MAP_WORLD_X ); /* // if enemies formerly controlled this sector if (StrategicMap[ usMapSector ].fEnemyControlled) { // remember that the enemies have lost it StrategicMap[ usMapSector ].fLostControlAtSomeTime = TRUE; } */ if( NumHostilesInSector( sMapX, sMapY, bMapZ ) ) { //too premature: enemies still in sector. return FALSE; } // check if we ever grabbed drassen airport, if so, set fact we can go to BR's if( ( sMapX == BOBBYR_SHIPPING_DEST_SECTOR_X ) && ( sMapY == BOBBYR_SHIPPING_DEST_SECTOR_Y ) ) { LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE; //If the player has been to Bobbyr when it was down, and we havent already sent email, send him an email if( LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction == BOBBYR_BEEN_TO_SITE_ONCE && LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction != BOBBYR_ALREADY_SENT_EMAIL ) { AddEmail( BOBBYR_NOW_OPEN, BOBBYR_NOW_OPEN_LENGTH, BOBBY_R, GetWorldTotalMin()); LaptopSaveInfo.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction = BOBBYR_ALREADY_SENT_EMAIL; } } fWasEnemyControlled = StrategicMap[ usMapSector ].fEnemyControlled; StrategicMap[ usMapSector ].fEnemyControlled = FALSE; SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE; bTownId = StrategicMap[ usMapSector ].bNameId; // check if there's a town in the sector if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) { // yes, start tracking (& displaying) this town's loyalty if not already doing so StartTownLoyaltyIfFirstTime( bTownId ); } // if player took control away from enemy if( fWasEnemyControlled && fContested ) { // and it's a town if ((bTownId >= FIRST_TOWN) && (bTownId < NUM_TOWNS)) { // don't do these for takeovers of Omerta sectors at the beginning of the game if ((bTownId != OMERTA) || (GetWorldDay() != 1)) { ubSectorID = (UINT8)SECTOR( sMapX, sMapY ); if( !bMapZ && ubSectorID != SEC_J9 && ubSectorID != SEC_K4 ) { HandleMoraleEvent( NULL, MORALE_TOWN_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_TOWN_SECTOR, sMapX, sMapY, bMapZ ); // liberation by definition requires that the place was enemy controlled in the first place CheckIfEntireTownHasBeenLiberated( bTownId, sMapX, sMapY ); } } } // if it's a mine that's still worth something if ( IsThereAMineInThisSector( sMapX, sMapY ) ) { if ( GetTotalLeftInMine( GetMineIndexForSector( sMapX, sMapY ) ) > 0) { HandleMoraleEvent( NULL, MORALE_MINE_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_MINE, sMapX, sMapY, bMapZ ); } } // if it's a SAM site sector if( IsThisSectorASAMSector( sMapX, sMapY, bMapZ ) ) { if ( 1 /*!GetSectorFlagStatus( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE ) */) { // SAM site liberated for first time, schedule meanwhile HandleMeanWhileEventPostingForSAMLiberation( GetSAMIdFromSector( sMapX, sMapY, bMapZ ) ); } HandleMoraleEvent( NULL, MORALE_SAM_SITE_LIBERATED, sMapX, sMapY, bMapZ ); HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_GAIN_SAM, sMapX, sMapY, bMapZ ); // if Skyrider has been delivered to chopper, and already mentioned Drassen SAM site, but not used this quote yet if ( IsHelicopterPilotAvailable() && ( guiHelicopterSkyriderTalkState >= 1 ) && ( !gfSkyriderSaidCongratsOnTakingSAM ) ) { SkyRiderTalk( SAM_SITE_TAKEN ); gfSkyriderSaidCongratsOnTakingSAM = TRUE; } if ( !SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled ) { // grant grace period if ( gGameOptions.ubDifficultyLevel >= DIF_LEVEL_HARD ) { UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 2 ) ); } else { UpdateLastDayOfPlayerActivity( ( UINT16 ) ( GetWorldDay() + 1 ) ); } } } // if it's a helicopter refueling site sector if( IsRefuelSiteInSector( sMapX, sMapY) ) { UpdateRefuelSiteAvailability( ); } // SetSectorFlag( sMapX, sMapY, bMapZ, SF_SECTOR_HAS_BEEN_LIBERATED_ONCE ); if ( bMapZ == 0 && ( ( sMapY == MAP_ROW_M && (sMapX >= 2 && sMapX <= 6) ) || sMapY == MAP_ROW_N && sMapX == 6) ) { HandleOutskirtsOfMedunaMeanwhileScene(); } } if( fContested ) { StrategicHandleQueenLosingControlOfSector( (UINT8)sMapX, (UINT8)sMapY, (UINT8)bMapZ ); } } else { if( sMapX == 3 && sMapY == 16 && bMapZ == 1 ) { //Basement sector (P3_b1) gfUseAlternateQueenPosition = TRUE; } } // also set fact the player knows they own it SectorInfo[ SECTOR( sMapX, sMapY ) ].fPlayer[ bMapZ ] = TRUE; if ( bMapZ == 0 ) { SectorInfo[ SECTOR( sMapX, sMapY ) ].fSurfaceWasEverPlayerControlled = TRUE; } //KM : Aug 11, 1999 -- Patch fix: Relocated this check so it gets called everytime a sector changes hands, // even if the sector isn't a SAM site. There is a bug _somewhere_ that fails to update the airspace, // even though the player controls it. UpdateAirspaceControl( ); // redraw map/income if in mapscreen fMapPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; return fWasEnemyControlled; }
// MercDailyUpdate() gets called every day at midnight. If something is to happen to a merc that day, add an event for it. void MercDailyUpdate() { INT32 cnt; INT8 bLastTeamID; SOLDIERTYPE *pSoldier; //SOLDIERTYPE *pQuitList[ 21 ]; MERCPROFILESTRUCT *pProfile; UINT32 uiChance; INT32 iOffset = 0; BOOLEAN fFoundSomeOneForMenuShowing = FALSE; //if its the first day, leave if( GetWorldDay() == 1 ) return; // debug message ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s - Doing MercDailyUpdate", WORLDTIMESTR ); // if the death rate is very low (this is independent of mercs' personal deathrate tolerances) if (CalcDeathRate() < 5) { // everyone gets a morale bonus, which also gets player a reputation bonus. HandleMoraleEvent( NULL, MORALE_LOW_DEATHRATE, -1, -1, -1 ); } //add an event so the merc will say the departing warning ( 2 hours prior to leaving // Do so for all time slots they will depart from AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_1 - ( 2 * 60 ), 0 ); AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_2 - ( 2 * 60 ), 0 ); AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_3 - ( 2 * 60 ), 0 ); AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_1, 0 ); AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_2, 0 ); AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_3, 0 ); cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID; //loop though all the mercs for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++) { //if the merc is active if ( ( pSoldier->bActive )&&( pSoldier->bAssignment != ASSIGNMENT_POW ) && ( pSoldier->bAssignment != IN_TRANSIT ) ) { //CJC: Reset dialogue flags for quotes that can be said once/day pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_ANNOYING_MERC ); // ATE: Reset likes gun flag pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_LIKESGUN ); // ATE: Reset seen corpse flag pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_ROTTINGCORPSE ); // ATE; Reset found something nice flag... pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE ); // ATE: Decrement tolerance value... pSoldier->bCorpseQuoteTolerance--; if ( pSoldier->bCorpseQuoteTolerance < 0 ) { pSoldier->bCorpseQuoteTolerance = 0; } // CJC: For some personalities, reset personality quote said flag if ( pSoldier->ubProfile != NO_PROFILE ) { switch( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait ) { case HEAT_INTOLERANT: case CLAUSTROPHOBIC: case NONSWIMMER: case FEAR_OF_INSECTS: // repeatable once per day pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_PERSONALITY ); break; default: break; } } //ATE: Try to see if our equipment sucks! if ( SoldierHasWorseEquipmentThanUsedTo( pSoldier ) ) { // Randomly anytime between 6:00, and 10:00 AddSameDayStrategicEvent( EVENT_MERC_COMPLAIN_EQUIPMENT, 360 + Random( 1080 ) , pSoldier->ubProfile ); } // increment days served by this grunt gMercProfiles[pSoldier->ubProfile].usTotalDaysServed++; // player has hired him, so he'll eligible to get killed off on another job gMercProfiles[pSoldier->ubProfile].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE; //if the character is an RPC if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC ) { INT16 sSalary = gMercProfiles[ pSoldier->ubProfile ].sSalary; INT32 iMoneyOwedToMerc = 0; //increment the number of days the mercs has been on the team pSoldier->iTotalContractLength++; //if the player owes the npc money, the balance field will be negative if( gMercProfiles[ pSoldier->ubProfile ].iBalance < 0 ) { //the player owes the npc the salary and whatever money the player owes the npc iMoneyOwedToMerc = sSalary + ( - gMercProfiles[ pSoldier->ubProfile ].iBalance ); } else { //else the player only owes the salary iMoneyOwedToMerc = sSalary; } //if the player owes money if( iMoneyOwedToMerc != 0 ) { //if the player can afford to pay them if( LaptopSaveInfo.iCurrentBalance >= iMoneyOwedToMerc ) { //add the transaction to the player AddTransactionToPlayersBook( PAYMENT_TO_NPC, pSoldier->ubProfile, GetWorldTotalMin(), -iMoneyOwedToMerc); //if the player owed money to the npc if( gMercProfiles[ pSoldier->ubProfile ].iBalance < 0 ) { // reset the amount gMercProfiles[ pSoldier->ubProfile ].iBalance = 0; } } else { CHAR16 zMoney[128]; //create a string for the salary owed to the npc swprintf( zMoney, L"%d", sSalary ); InsertCommasForDollarFigure( zMoney ); InsertDollarSignInToString( zMoney ); //Display a screen msg indicating that the npc was NOT paid ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, pMessageStrings[ MSG_CANT_AFFORD_TO_PAY_NPC_DAILY_SALARY_MSG ], gMercProfiles[ pSoldier->ubProfile ].zNickname, zMoney ); //if the merc hasnt been paid for NUM_DAYS_TILL_UNPAID_RPC_QUITS days, the merc will quit if( ( gMercProfiles[ pSoldier->ubProfile ].iBalance - sSalary ) <= -( sSalary * NUM_DAYS_TILL_UNPAID_RPC_QUITS ) ) { // //Set it up so the merc quits // MercsContractIsFinished( pSoldier->ubID ); } else { //set how much money the player owes the merc gMercProfiles[ pSoldier->ubProfile ].iBalance -= sSalary; // Add even for displaying a dialogue telling the player this.... AddSameDayStrategicEvent( EVENT_RPC_WHINE_ABOUT_PAY, MERC_ARRIVE_TIME_SLOT_1, pSoldier->ubID ); } } } } DailyMoraleUpdate( pSoldier ); CheckIfMercGetsAnotherContract( pSoldier ); } else { if( ( pSoldier->bActive ) && ( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { pSoldier->iEndofContractTime += 1440; } } // if active, here, & alive (POW is ok, don't care) if( ( pSoldier->bActive ) && ( pSoldier->bAssignment != ASSIGNMENT_DEAD ) && ( pSoldier->bAssignment != IN_TRANSIT ) ) { // increment the "man days" played counter for each such merc in the player's employment gStrategicStatus.uiManDaysPlayed++; } } //r eset the counter cnt = 0; for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++) { //if the merc is active if ( ( pSoldier->bActive )&&( pSoldier->bAssignment != ASSIGNMENT_POW ) && ( pSoldier->bAssignment != IN_TRANSIT ) ) { //if its a MERC merc, determine if the merc should leave ( because player refused to pay for merc ) if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) { //if the players account status is invalid if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_INVALID ) { //if the soldier is alive anc concious if( IsTheSoldierAliveAndConcious( pSoldier ) ) { //if the merc should leave today MercsContractIsFinished( pSoldier->ubID ); } } } } } //Loop through all the profiles for( cnt = 0; cnt < NUM_PROFILES; cnt++) { pProfile = &(gMercProfiles[ cnt ]); // dead guys don't do nuthin' ! if ( pProfile->bMercStatus == MERC_IS_DEAD ) { continue; } //Every day reset this variable pProfile->uiPrecedentQuoteSaid = 0; // skip anyone currently on the player's team if ( IsMercOnTeam( (UINT8) cnt )) { continue; } // if he's an AIM/M.E.R.C. merc if ( cnt < AIM_AND_MERC_MERCS ) { // if he's not just on his way home if ( pProfile->bMercStatus != MERC_RETURNING_HOME ) { // check if any of his stats improve through working or training HandleUnhiredMercImprovement(pProfile); // if he's working on another job if (pProfile->bMercStatus == MERC_WORKING_ELSEWHERE) { // check if he's killed HandleUnhiredMercDeaths( cnt ); } } } // if merc is currently unavailable if( pProfile->uiDayBecomesAvailable > 0 ) { // reduce time til available by one day pProfile->uiDayBecomesAvailable--; // Check to see if the merc has become available if (pProfile->uiDayBecomesAvailable == 0) { //if the merc CAN become ready if( pProfile->bMercStatus != MERC_FIRED_AS_A_POW ) { pProfile->bMercStatus = MERC_OK; // if the player has left a message for this merc if ( pProfile->ubMiscFlags3 & PROFILE_MISC_FLAG3_PLAYER_LEFT_MSG_FOR_MERC_AT_AIM ) { iOffset = AIM_REPLY_BARRY; //remove the Flag, so if the merc goes on another assignment, the player can leave an email. pProfile->ubMiscFlags3 &= ~PROFILE_MISC_FLAG3_PLAYER_LEFT_MSG_FOR_MERC_AT_AIM; // TO DO: send E-mail to player telling him the merc has returned from an assignment AddEmail( ( UINT8 )( iOffset + ( cnt * AIM_REPLY_LENGTH_BARRY ) ), AIM_REPLY_LENGTH_BARRY, ( UINT8 )( 6 + cnt ), GetWorldTotalMin() ); } } } } else // was already available today { // if it's an AIM or M.E.R.C. merc if (cnt < AIM_AND_MERC_MERCS) { // check to see if he goes on another assignment if (cnt < MAX_NUMBER_MERCS) { // A.I.M. merc uiChance = 2 * pProfile->bExpLevel; // player has now had a chance to hire him, so he'll eligible to get killed off on another job pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE; } else { // M.E.R.C. merc - very rarely get other work uiChance = 1 * pProfile->bExpLevel; // player doesn't have a chance to hire any M.E.R.C's until after Speck's E-mail is sent if (GetWorldDay() > DAYS_TIL_M_E_R_C_AVAIL) { // player has now had a chance to hire him, so he'll eligible to get killed off on another job pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE; } } if (Random(100) < uiChance) { pProfile->bMercStatus = MERC_WORKING_ELSEWHERE; pProfile->uiDayBecomesAvailable = 1 + Random(6 + (pProfile->bExpLevel / 2) ); // 1-(6 to 11) days } } } // Decrement morale hangover (merc appears hirable, he just gives lame refusals during this time, though) if( pProfile->ubDaysOfMoraleHangover > 0 ) { pProfile->ubDaysOfMoraleHangover--; } } // build quit list //BuildMercQuitList( pQuitList ); HandleSlayDailyEvent( ); // rebuild list for mapscreen ReBuildCharactersList( ); }