void TriggerEndOfBoxingRecord( SOLDIERTYPE * pSoldier ) { // unlock UI guiPendingOverrideEvent = LU_ENDUILOCK; if ( pSoldier ) { switch( gTacticalStatus.bBoxingState ) { case WON_ROUND: AddHistoryToPlayersLog( HISTORY_WON_BOXING, pSoldier->ubProfile, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); TriggerNPCRecord( DARREN, 23 ); break; case LOST_ROUND: // log as lost AddHistoryToPlayersLog( HISTORY_LOST_BOXING, pSoldier->ubProfile, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); TriggerNPCRecord( DARREN, 24 ); break; case DISQUALIFIED: AddHistoryToPlayersLog( HISTORY_DISQUALIFIED_BOXING, pSoldier->ubProfile, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); break; } } SetBoxingState( NOT_BOXING ); }
void ShutOffMineProduction( INT8 bMineIndex ) { Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) ); if ( !gMineStatus[ bMineIndex ].fShutDown ) { gMineStatus[ bMineIndex ].fShutDown = TRUE; AddHistoryToPlayersLog( HISTORY_MINE_SHUTDOWN, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } }
void GameInitHistory() { if( ( FileExists( HISTORY_DATA_FILE ) ) ) { // unlink history file FileClearAttributes( HISTORY_DATA_FILE ); FileDelete( HISTORY_DATA_FILE ); } AddHistoryToPlayersLog(HISTORY_ACCEPTED_ASSIGNMENT_FROM_ENRICO, 0, GetWorldTotalMin( ), -1, -1); }
void RestartMineProduction( INT8 bMineIndex ) { Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) ); if ( !gMineStatus[ bMineIndex ].fShutDownIsPermanent ) { if ( gMineStatus[ bMineIndex ].fShutDown ) { gMineStatus[ bMineIndex ].fShutDown = FALSE; AddHistoryToPlayersLog( HISTORY_MINE_REOPENED, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } } }
void PlayerSpokeToHeadMiner( UINT8 ubMinerProfileId ) { UINT8 ubMineIndex; ubMineIndex = GetHeadMinersMineIndex( ubMinerProfileId ); // if this is our first time set a history fact if( gMineStatus[ ubMineIndex ].fSpokeToHeadMiner == FALSE ) { AddHistoryToPlayersLog( HISTORY_TALKED_TO_MINER, gMineLocation[ ubMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ ubMineIndex ].sSectorX, gMineLocation[ ubMineIndex ].sSectorY ); gMineStatus[ ubMineIndex ].fSpokeToHeadMiner = TRUE; } }
BOOLEAN QuickGameMemberHireMerc( UINT8 ubCurrentSoldier ) { MERC_HIRE_STRUCT HireMercStruct; memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT)); HireMercStruct.ubProfileID = ubCurrentSoldier; HireMercStruct.sSectorX = gsMercArriveSectorX; HireMercStruct.sSectorY = gsMercArriveSectorY; HireMercStruct.fUseLandingZoneForArrival = TRUE; HireMercStruct.fCopyProfileItemsOver = TRUE; HireMercStruct.ubInsertionCode = INSERTION_CODE_CHOPPER; HireMercStruct.iTotalContractLength = 7; //specify when the merc should arrive HireMercStruct.uiTimeTillMercArrives = 0; //if we succesfully hired the merc if( !HireMerc( &HireMercStruct ) ) { return(FALSE); } //add an entry in the finacial page for the hiring of the merc AddTransactionToPlayersBook(HIRED_MERC, ubCurrentSoldier, GetWorldTotalMin(), -(INT32) gMercProfiles[ubCurrentSoldier].uiWeeklySalary ); if( gMercProfiles[ ubCurrentSoldier ].bMedicalDeposit ) { //add an entry in the finacial page for the medical deposit AddTransactionToPlayersBook(MEDICAL_DEPOSIT, ubCurrentSoldier, GetWorldTotalMin(), -(gMercProfiles[ubCurrentSoldier].sMedicalDepositAmount) ); } //add an entry in the history page for the hiring of the merc AddHistoryToPlayersLog( HISTORY_HIRED_MERC_FROM_AIM, ubCurrentSoldier, GetWorldTotalMin(), -1, -1 ); return(TRUE); }
void BoxingMovementCheck( SOLDIERTYPE * pSoldier ) { //DBrot: More Rooms //UINT8 ubRoom; UINT16 usRoom; if ( InARoom( pSoldier->sGridNo, &usRoom ) && usRoom == BOXING_RING) { // someone moving in/into the ring CountPeopleInBoxingRingAndDoActions(); } else if ( ( gTacticalStatus.bBoxingState == BOXING ) && ( pSoldier->flags.uiStatusFlags & SOLDIER_BOXER ) ) { // boxer stepped out of the ring! BoxingPlayerDisqualified( pSoldier, BOXER_OUT_OF_RING ); // add the history record here. AddHistoryToPlayersLog( HISTORY_DISQUALIFIED_BOXING, pSoldier->ubProfile, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY ); // make not a boxer any more pSoldier->DeleteBoxingFlag( ); pSoldier->flags.uiStatusFlags &= (~SOLDIER_PCUNDERAICONTROL); } }
BOOLEAN RecruitRPC( UINT8 ubCharNum ) { SOLDIERTYPE *pSoldier, *pNewSoldier; // Get soldier pointer pSoldier = FindSoldierByProfileID( ubCharNum, FALSE ); if (!pSoldier) { return( FALSE ); } // OK, set recruit flag.. gMercProfiles[ ubCharNum ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED; // Add this guy to our team! pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum ); // handle set up any RPC's that will leave us in time if ( ubCharNum == SLAY ) { // slay will leave in a week pNewSoldier->iEndofContractTime = GetWorldTotalMin() + ( 7 * 24 * 60 ); KickOutWheelchair( pNewSoldier ); } else if ( ubCharNum == DYNAMO && gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS ) { EndQuest( QUEST_FREE_DYNAMO, pSoldier->sSectorX, pSoldier->sSectorY ); } // handle town loyalty adjustment HandleTownLoyaltyForNPCRecruitment( pNewSoldier ); // Try putting them into the current squad if ( AddCharacterToSquad( pNewSoldier, (INT8)CurrentSquad( ) ) == FALSE ) { AddCharacterToAnySquad( pNewSoldier ); } ResetDeadSquadMemberList( pNewSoldier->bAssignment ); DirtyMercPanelInterface( pNewSoldier, DIRTYLEVEL2 ); if ( pNewSoldier->inv[ HANDPOS ].usItem == NOTHING ) { // empty handed - swap in first available weapon INT8 bSlot; bSlot = FindObjClass( pNewSoldier, IC_WEAPON ); if ( bSlot != NO_SLOT ) { if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].fFlags & ITEM_TWO_HANDED ) { if ( bSlot != SECONDHANDPOS && pNewSoldier->inv[ SECONDHANDPOS ].usItem != NOTHING ) { // need to move second hand item out first AutoPlaceObject( pNewSoldier, &(pNewSoldier->inv[ SECONDHANDPOS ]), FALSE ); } } // swap item to hand SwapObjs( &(pNewSoldier->inv[ bSlot ]), &(pNewSoldier->inv[ HANDPOS ]) ); } } #ifdef JA2DEMO HandleEndDemoInCreatureLevel( ); #endif if ( ubCharNum == IRA ) { // trigger 0th PCscript line TriggerNPCRecord( IRA, 0 ); } // Set whatkind of merc am i pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__NPC; // //add a history log that tells the user that a npc has joined the team // // ( pass in pNewSoldier->sSectorX cause if its invalid, -1, n/a will appear as the sector in the history log ) AddHistoryToPlayersLog( HISTORY_RPC_JOINED_TEAM, pNewSoldier->ubProfile, GetWorldTotalMin(), pNewSoldier->sSectorX, pNewSoldier->sSectorY ); //remove the merc from the Personnel screens departed list ( if they have never been hired before, its ok to call it ) RemoveNewlyHiredMercFromPersonnelDepartedList( pSoldier->ubProfile ); return( TRUE ); }
BOOLEAN StrategicRemoveMerc( SOLDIERTYPE *pSoldier ) { UINT8 ubHistoryCode=0; if ( gfInContractMenuFromRenewSequence ) { EndCurrentContractRenewal( ); } // ATE: Determine which HISTORY ENTRY to use... if ( pSoldier->ubLeaveHistoryCode == 0 ) { // Default use contract expired reason... pSoldier->ubLeaveHistoryCode = HISTORY_MERC_CONTRACT_EXPIRED; } ubHistoryCode = pSoldier->ubLeaveHistoryCode; //if the soldier is DEAD if( pSoldier->stats.bLife <= 0 ) { AddCharacterToDeadList( pSoldier ); } //else if the merc was fired else if( ubHistoryCode == HISTORY_MERC_FIRED || pSoldier->bAssignment == ASSIGNMENT_POW ) { AddCharacterToFiredList( pSoldier ); } //The merc is leaving for some other reason else { AddCharacterToOtherList( pSoldier ); } if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC ) { SetupProfileInsertionDataForSoldier( pSoldier ); } if (IsVehicle(pSoldier)) { // for some reason, vehicles have their own idea of handling group ids RemovePlayerFromGroup(pVehicleList[ pSoldier->bVehicleID ].ubMovementGroup, pSoldier); } //remove him from the soldier structure if( pSoldier->bAssignment >= ON_DUTY ) { // is he/she in a mvt group, if so, remove and destroy the group if( pSoldier->ubGroupID ) { if ( pSoldier->bAssignment != VEHICLE ) { //Can only remove groups if they aren't persistant (not in a squad or vehicle) RemoveGroup( pSoldier->ubGroupID ); } else { // remove him from any existing merc slot he could be in RemoveMercSlot( pSoldier ); TakeSoldierOutOfVehicle( pSoldier ); } } } else { RemoveCharacterFromSquads( pSoldier ); } // if the merc is not dead if( gMercProfiles[ pSoldier->ubProfile ].bMercStatus != MERC_IS_DEAD ) { //Set the status to returning home ( delay the merc for rehire ) gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_RETURNING_HOME; // specify how long the merc will continue to be unavailable gMercProfiles[ pSoldier->ubProfile ].uiDayBecomesAvailable = 1 + Random(2); // 1-2 days HandleSoldierLeavingWithLowMorale( pSoldier ); HandleSoldierLeavingForAnotherContract( pSoldier ); } //add an entry in the history page for the firing/quiting of the merc // ATE: Don't do this if they are already dead! if ( !( pSoldier->flags.uiStatusFlags & SOLDIER_DEAD ) ) { AddHistoryToPlayersLog( ubHistoryCode, pSoldier->ubProfile, GetWorldTotalMin(), pSoldier->sSectorX, pSoldier->sSectorY ); } //if the merc was a POW, remember it becuase the merc cant show up in AIM or MERC anymore if( pSoldier->bAssignment == ASSIGNMENT_POW ) { gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_FIRED_AS_A_POW; } //else the merc CAN get his medical deposit back else { //Determine how much of a Medical deposit is going to be refunded to the player CalculateMedicalDepositRefund( pSoldier ); } //remove the merc from the tactical TacticalRemoveSoldier( pSoldier->ubID ); // Check if we should remove loaded world... CheckAndHandleUnloadingOfCurrentWorld(); if ( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN ) { ReBuildCharactersList( ); } fMapPanelDirty = TRUE; fTeamPanelDirty = TRUE; fCharacterInfoPanelDirty = TRUE; // stop time compression so player can react to the departure StopTimeCompression(); // WDS: This allows for replacing dead IMP mercs. See "BtnIMPBeginScreenDoneCallback" in "IMP Begin Screen.cpp" if( ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__PLAYER_CHARACTER ) && ( gMercProfiles[ pSoldier->ubProfile ].bMercStatus == MERC_IS_DEAD ) ) { // Replace the name with an empty string wcsncpy( gMercProfiles[ pSoldier->ubProfile ].zName, L"", 1 ); } // ATE: update team panels.... UpdateTeamPanelAssignments( ); // And unpause the @#$@#$ interface UnLockPauseState(); UnPauseGame(); if (is_client) send_dismiss(pSoldier->ubID); return( TRUE ); }
// This is used only to EXTEND the contract of an AIM merc already on the team BOOLEAN MercContractHandling( SOLDIERTYPE *pSoldier, UINT8 ubDesiredAction ) { INT32 iContractCharge=0; INT32 iContractLength=0; UINT8 ubHistoryContractType=0; UINT8 ubFinancesContractType=0; INT32 iCostOfInsurance = 0; //determins what kind of merc the contract is being extended for (only aim mercs can extend contract) if( pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__AIM_MERC ) return(FALSE); switch( ubDesiredAction ) { case CONTRACT_EXTEND_1_DAY: //check to see if the merc has enough money iContractCharge = gMercProfiles[ pSoldier->ubProfile ].sSalary; //set the contract length and the charge iContractLength = 1; ubHistoryContractType = HISTORY_EXTENDED_CONTRACT_1_DAY; ubFinancesContractType = EXTENDED_CONTRACT_BY_1_DAY; break; case CONTRACT_EXTEND_1_WEEK: iContractCharge = gMercProfiles[ pSoldier->ubProfile ].uiWeeklySalary; //set the contract length and the charge iContractLength = 7; ubHistoryContractType = HISTORY_EXTENDED_CONTRACT_1_WEEK; ubFinancesContractType = EXTENDED_CONTRACT_BY_1_WEEK; break; case CONTRACT_EXTEND_2_WEEK: iContractCharge = gMercProfiles[ pSoldier->ubProfile ].uiBiWeeklySalary; //set the contract length and the charge iContractLength = 14; ubHistoryContractType = HISTORY_EXTENDED_CONTRACT_2_WEEK; ubFinancesContractType = EXTENDED_CONTRACT_BY_2_WEEKS; break; default: return(FALSE); break; } //check to see if the merc has enough money if( LaptopSaveInfo.iCurrentBalance < iContractCharge ) return(FALSE); //Check to see if merc will renew if( !WillMercRenew( pSoldier, TRUE ) ) { // Remove soldier.... ( if this is setup because normal contract ending dequence... ) if ( ContractIsExpiring( pSoldier ) ) { TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING, 1,0 ); } return(FALSE); } fPausedTimeDuringQuote = TRUE; SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,1 ,MAP_SCREEN ,0 ,0 ,0 ); // // These calcs need to be done before Getting/Calculating the insurance costs // //set the contract length and the charge pSoldier->iTotalContractLength += iContractLength; // pSoldier->iTotalContractCharge = iContractCharge; pSoldier->bTypeOfLastContract = ubDesiredAction; //determine the end of the contract pSoldier->iEndofContractTime += ( iContractLength * 1440 ); if( ( pSoldier->usLifeInsurance ) && ( pSoldier->bAssignment != ASSIGNMENT_POW ) ) // DEF: Removed cause they can extend a 1 day contract && ( iContractLength > 1 ) { // check if player can afford insurance, if not, tell them iCostOfInsurance = CalculateInsuranceContractCost( iContractLength, pSoldier->ubProfile ); HandleImportantMercQuote( pSoldier, QUOTE_ACCEPT_CONTRACT_RENEWAL ); if( iCostOfInsurance > LaptopSaveInfo.iCurrentBalance ) { // no can afford HandleNotifyPlayerCantAffordInsurance( ); // OK, handle ending of renew session if ( gfInContractMenuFromRenewSequence ) { EndCurrentContractRenewal( ); } } else { // can afford ask if they want it HandleNotifyPlayerCanAffordInsurance( pSoldier, ( UINT8 )( iContractLength ), iCostOfInsurance ); } } else { // no need to query for life insurance HandleImportantMercQuote( pSoldier, QUOTE_ACCEPT_CONTRACT_RENEWAL ); // OK, handle ending of renew session if ( gfInContractMenuFromRenewSequence ) { EndCurrentContractRenewal( ); } } SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,0 ,MAP_SCREEN ,0 ,0 ,0 ); // ATE: Setup when they can be signed again! // If they are 2-weeks this can be extended // otherwise don't change from current if ( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_2_WEEK ) { pSoldier->iTimeCanSignElsewhere = pSoldier->iEndofContractTime; } // ARM: Do not reset because of renewal! The quote is for early dismissal from *initial* time of hiring // pSoldier->uiTimeOfLastContractUpdate = GetWorldTotalMin(); // ARM: Do not reset because of renewal! The deposit in the profile goes up when merc levels, but the one in the soldier // structure must always reflect the deposit actually paid (which does NOT change when a merc levels). // pSoldier->usMedicalDeposit = gMercProfiles[ pSoldier->ubProfile ].sMedicalDepositAmount; //add an entry in the finacial page for the extending of the mercs contract AddTransactionToPlayersBook( ubFinancesContractType, pSoldier->ubProfile, GetWorldTotalMin(), -iContractCharge ); //add an entry in the history page for the extending of the merc contract AddHistoryToPlayersLog( ubHistoryContractType, pSoldier->ubProfile, GetWorldTotalMin(), pSoldier->sSectorX, pSoldier->sSectorY ); return( TRUE ); }
void StrategicHandlePlayerTeamMercDeath( SOLDIERTYPE *pSoldier ) { SOLDIERTYPE *pKiller = NULL; INT16 sSectorX, sSectorY; //if the soldier HAS a profile if( pSoldier->ubProfile != NO_PROFILE ) { //add to the history log the fact that the merc died and the circumstances if( pSoldier->ubAttackerID != NOBODY ) { pKiller = MercPtrs[ pSoldier->ubAttackerID ]; } // CJC Nov 11, 2002 // Use the soldier's sector location unless impossible if (pSoldier->sSectorX != 0 && pSoldier->sSectorY != 0) { sSectorX = pSoldier->sSectorX; sSectorY = pSoldier->sSectorY; } else { sSectorX = gWorldSectorX; sSectorY = gWorldSectorY; } if( pKiller && pKiller->bTeam == OUR_TEAM ) { AddHistoryToPlayersLog( HISTORY_MERC_KILLED_CHARACTER, pSoldier->ubProfile, GetWorldTotalMin(), sSectorX, sSectorY ); } else { AddHistoryToPlayersLog( HISTORY_MERC_KILLED, pSoldier->ubProfile, GetWorldTotalMin(), sSectorX, sSectorY ); } } if ( guiCurrentScreen != GAME_SCREEN ) { ScreenMsg( FONT_RED, MSG_INTERFACE, pMercDeadString[ 0 ], pSoldier->name ); } // robot and EPCs don't count against death rate - the mercs back home don't particularly give a damn about locals & machines! if ( !AM_AN_EPC( pSoldier ) && !AM_A_ROBOT( pSoldier ) ) { // keep track of how many mercs have died under player's command (for death rate, can't wait until removed from team) gStrategicStatus.ubMercDeaths++; } pSoldier->uiStatusFlags |= SOLDIER_DEAD; // Set breath to 0! pSoldier->bBreathMax = pSoldier->bBreath = 0; // not asleep, DEAD! pSoldier->fMercAsleep = FALSE; //if the merc had life insurance if( pSoldier->usLifeInsurance ) { // if he didn't die during auto-resolve if( guiCurrentScreen != AUTORESOLVE_SCREEN ) { // check whether this was obviously a suspicious death // if killed within an hour of being insured if ( pSoldier->uiStartTimeOfInsuranceContract <= GetWorldTotalMin() && GetWorldTotalMin() - pSoldier->uiStartTimeOfInsuranceContract < 60 ) { gMercProfiles[ pSoldier->ubProfile ].ubSuspiciousDeath = VERY_SUSPICIOUS_DEATH; } // if killed by someone on our team, or while there weren't any opponents around else if (Menptr[ pSoldier->ubAttackerID ].bTeam == OUR_TEAM || !gTacticalStatus.fEnemyInSector ) { // cause insurance company to suspect fraud and investigate this claim gMercProfiles[ pSoldier->ubProfile ].ubSuspiciousDeath = SUSPICIOUS_DEATH; } } AddLifeInsurancePayout( pSoldier ); } // robot and EPCs don't penalize morale - merc don't care about fighting machines and the lives of locals much if ( !AM_AN_EPC( pSoldier ) && !AM_A_ROBOT( pSoldier ) ) { // Change morale of others based on this HandleMoraleEvent( pSoldier, MORALE_TEAMMATE_DIED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); } //if its a MERC merc, record the time of his death if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) { pSoldier->iEndofContractTime = GetWorldTotalMin(); //set is so Speck can say that a merc is dead LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote = 1; } //Set the fact that the merc is DEAD!! gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_IS_DEAD; if( pSoldier->bAssignment != ASSIGNMENT_DEAD ) { SetTimeOfAssignmentChangeForMerc( pSoldier ); } // handle strategic level death HandleStrategicDeath( pSoldier ); }
UINT32 ExtractOreFromMine( INT8 bMineIndex, UINT32 uiAmount ) { // will remove the ore from the mine and return the amount that was removed UINT32 uiAmountExtracted = 0; UINT32 uiOreRunningOutPoint = 0; INT16 sSectorX, sSectorY; Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) ); // if mine is shut down if ( gMineStatus[ bMineIndex ].fShutDown) { return ( 0 ); } // if not capable of extracting anything, bail now if (uiAmount == 0) { return ( 0 ); } // will this exhaust the ore in this mine? if( uiAmount >= gMineStatus[ bMineIndex ].uiRemainingOreSupply ) { // exhaust remaining ore uiAmountExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply; gMineStatus[ bMineIndex ].uiRemainingOreSupply = 0; gMineStatus[ bMineIndex ].uiMaxRemovalRate = 0; gMineStatus[ bMineIndex ].fEmpty = TRUE; gMineStatus[ bMineIndex ].fRunningOut = FALSE; // tell the strategic AI about this, that mine's and town's value is greatly reduced GetMineSector( bMineIndex, &sSectorX, &sSectorY ); StrategicHandleMineThatRanOut( ( UINT8 ) SECTOR( sSectorX, sSectorY ) ); AddHistoryToPlayersLog( HISTORY_MINE_RAN_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } else // still some left after this extraction { // set amount used, and decrement ore remaining in mine uiAmountExtracted = uiAmount; gMineStatus[ bMineIndex ].uiRemainingOreSupply -= uiAmount; // one of the mines (randomly chosen) will start running out eventually, check if we're there yet if (gMineStatus[ bMineIndex ].uiRemainingOreSupply < gMineStatus[ bMineIndex ].uiOreRunningOutPoint) { gMineStatus[ bMineIndex ].fRunningOut = TRUE; // round all fractions UP to the next REMOVAL_RATE_INCREMENT gMineStatus[ bMineIndex ].uiMaxRemovalRate = (UINT32) (((FLOAT) gMineStatus[ bMineIndex ].uiRemainingOreSupply / 10) / REMOVAL_RATE_INCREMENT + 0.9999) * REMOVAL_RATE_INCREMENT; // if we control it if (PlayerControlsMine(bMineIndex)) { // and haven't yet been warned that it's running out if (!gMineStatus[ bMineIndex ].fWarnedOfRunningOut) { // that mine's head miner tells player that the mine is running out IssueHeadMinerQuote( bMineIndex, HEAD_MINER_STRATEGIC_QUOTE_RUNNING_OUT ); gMineStatus[ bMineIndex ].fWarnedOfRunningOut = TRUE; AddHistoryToPlayersLog( HISTORY_MINE_RUNNING_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY ); } } } } return( uiAmountExtracted ); }