// ATE: This function deals with MERC MERC and NPC's leaving because of not getting paid... // NOT AIM renewals.... void MercsContractIsFinished( UINT8 ubID ) { SOLDIERTYPE *pSoldier; #ifndef JA2DEMO pSoldier = &Menptr[ ubID ]; //if the soldier was removed before getting into this function, return if( !pSoldier->bActive ) return; if( fShowContractMenu ) { fShowContractMenu = FALSE; } // go to mapscreen SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_ENTER_MAPSCREEN,0,0,0,0,0 ); if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) { //if the players account status is invalid if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_INVALID ) { //Send the merc home InterruptTime( ); PauseGame(); LockPauseState( 9 ); // Say quote for wishing to leave TacticalCharacterDialogue( pSoldier, QUOTE_NOT_GETTING_PAID ); TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP, 0, 0 ); pSoldier->ubLeaveHistoryCode = HISTORY_MERC_QUIT; } } else if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC ) { InterruptTime( ); PauseGame(); LockPauseState( 10 ); TacticalCharacterDialogue( pSoldier, QUOTE_AIM_SEEN_MIKE ); TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP, 0, 0 ); pSoldier->ubLeaveHistoryCode = HISTORY_MERC_QUIT; } #endif }
void HourlyCheckIfSlayAloneSoHeCanLeave() { SOLDIERTYPE *pSoldier; pSoldier = FindSoldierByProfileID( SLAY, TRUE ); if( !pSoldier ) { return; } if( pSoldier->fBetweenSectors ) { return; } if( !pSoldier->bActive || !pSoldier->bLife ) { return; } if( PlayerMercsInSector( (UINT8)pSoldier->sSectorX, (UINT8)pSoldier->sSectorY, pSoldier->bSectorZ ) == 1 ) { if( Chance( 15 ) ) { pSoldier->ubLeaveHistoryCode = HISTORY_SLAY_MYSTERIOUSLY_LEFT; TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING_NO_ASK_EQUIP, 0, 0 ); } } }
void HandleMercIsNotWillingToRenew( UINT8 ubID ) { SOLDIERTYPE *pSoldier = MercPtrs[ ubID ]; // We wish to lock interface SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,1,MAP_SCREEN,0,0,0 ); // Setup variable for this.... gfInContractMenuFromRenewSequence = TRUE; // Show contract menu TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_SHOW_CONTRACT_MENU, 0,0 ); // Unlock now SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,0 ,MAP_SCREEN ,0 ,0 ,0 ); }
void HandleRPCDescription( ) { // WDS - make number of mercenaries, etc. be configurable std::vector<UINT8> ubMercsInSector (CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS, 0); // UINT8 ubMercsInSector[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 }; UINT8 ubNumMercs = 0; UINT8 ubChosenMerc; SOLDIERTYPE *pTeamSoldier; INT32 cnt2; BOOLEAN fSAMSite = FALSE; if ( !gTacticalStatus.fCountingDownForGuideDescription ) { return; } // ATE: postpone if we are not in tactical if ( guiCurrentScreen != GAME_SCREEN ) { return; } if ( ( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) ) { return; } // Are we a SAM site? if ( gTacticalStatus.ubGuideDescriptionToUse == 27 || gTacticalStatus.ubGuideDescriptionToUse == 30 || gTacticalStatus.ubGuideDescriptionToUse == 32 || gTacticalStatus.ubGuideDescriptionToUse == 25 || gTacticalStatus.ubGuideDescriptionToUse == 31 ) { fSAMSite = TRUE; gTacticalStatus.bGuideDescriptionCountDown = 1; } // ATE; Don't do in combat if ( ( gTacticalStatus.uiFlags & INCOMBAT ) && !fSAMSite ) { return; } // Don't do if enemy in sector if ( NumEnemyInSector( ) && !fSAMSite ) { return; } gTacticalStatus.bGuideDescriptionCountDown--; if ( gTacticalStatus.bGuideDescriptionCountDown == 0 ) { gTacticalStatus.fCountingDownForGuideDescription = FALSE; // OK, count how many rpc guys we have.... // set up soldier ptr as first element in mercptrs list cnt2 = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; // run through list for ( pTeamSoldier = MercPtrs[ cnt2 ]; cnt2 <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt2++,pTeamSoldier++ ) { // Add guy if he's a candidate... if ( RPC_RECRUITED( pTeamSoldier ) ) { if ( pTeamSoldier->stats.bLife >= OKLIFE && pTeamSoldier->bActive && pTeamSoldier->sSectorX == gTacticalStatus.bGuideDescriptionSectorX && pTeamSoldier->sSectorY == gTacticalStatus.bGuideDescriptionSectorY && pTeamSoldier->bSectorZ == gbWorldSectorZ && !pTeamSoldier->flags.fBetweenSectors ) { if ( pTeamSoldier->ubProfile == IRA || pTeamSoldier->ubProfile == MIGUEL || pTeamSoldier->ubProfile == CARLOS || pTeamSoldier->ubProfile == DIMITRI ) { ubMercsInSector[ ubNumMercs ] = (UINT8)cnt2; ubNumMercs++; } } } } // If we are > 0 if ( ubNumMercs > 0 ) { ubChosenMerc = (UINT8)Random( ubNumMercs ); TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ ubMercsInSector[ ubChosenMerc ] ], gTacticalStatus.ubGuideDescriptionToUse, DIALOGUE_SPECIAL_EVENT_USE_ALTERNATE_FILES, 0, 0 ); } } }
void RevealRoofsAndItems(SOLDIERTYPE *pSoldier, UINT32 itemsToo, BOOLEAN fShowLocators, UINT8 ubLevel, BOOLEAN fForce ) { INT32 maincnt,markercnt,marker,tilesLeftToSee,prevmarker; UINT8 cnt; INT32 Inc[6],Dir[6]; INT8 itemVisible = FALSE; INT8 Blocking,twoMoreTiles,markerDir; INT8 nextDir=0; UINT8 who; //,itemIndex; // for each square checked UINT8 dir,range,Path2; //DBrot: More Rooms //UINT8 ubRoomNo; UINT16 usRoomNo; BOOLEAN fCheckForRooms = FALSE; ITEM_POOL *pItemPool; BOOLEAN fHiddenStructVisible; UINT8 ubMovementCost; BOOLEAN fTravelCostObs; BOOLEAN fGoneThroughDoor = FALSE; BOOLEAN fThroughWindow = FALSE; BOOLEAN fItemsQuoteSaid = FALSE; UINT16 usIndex; BOOLEAN fRevealItems = TRUE; BOOLEAN fStopRevealingItemsAfterThisTile = FALSE; INT8 bTallestStructureHeight; INT32 iDoorGridNo; STRUCTURE *pStructure, *pDummy; INT8 bStructHeight; INT8 bThroughWindowDirection; if ( pSoldier->flags.uiStatusFlags & SOLDIER_ENEMY ) { //pSoldier->needToLookForItems = FALSE; return; } if ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) { return; } // Return if this guy has no gridno, has bad life, etc if(TileIsOutOfBounds(pSoldier->sGridNo) || !pSoldier->bInSector || pSoldier->stats.bLife < OKLIFE ) { return; } if (pSoldier->bBlindedCounter > 0) { return; } gubGridNoValue++; if ( gubGridNoValue == 255 ) { // Reset! Assert(gubGridNoMarkers); memset(gubGridNoMarkers, 0, sizeof(UINT8)*WORLD_MAX); gubGridNoValue = 1; } // OK, look for doors MercLooksForDoors( pSoldier, TRUE ); who = pSoldier->ubID; dir = pSoldier->ubDirection; //NumMessage("good old reveal",dir); // a gassed merc can only see 1 tile away due to blurred vision if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED ) { range = 1; } else { range = pSoldier->bViewRange; // Flugente: adjust sightrange range = (UINT8)( (range * (100 + pSoldier->GetSightRangeBonus()) ) / 100); // balance item viewing range between normal and the limit set by opplist-type functions -- CJC range = (AdjustMaxSightRangeForEnvEffects( pSoldier, LightTrueLevel( pSoldier->sGridNo, pSoldier->pathing.bLevel), range ) + range) / 2; } BuildSightDir(dir,(UINT32 *)&Dir[0],(UINT32 *)&Dir[1],(UINT32 *)&Dir[2],(UINT32 *)&Dir[3],(UINT32 *)&Dir[4]); for (cnt = 0; cnt < 5; cnt++) Inc[cnt] = DirectionInc( (UINT8) Dir[cnt]); // create gridno increment for NOVIEW - in other words, no increment! Inc[5] = 0; Dir[5] = pSoldier->ubDirection; if (dir % 2 == 1) /* even numbers use ViewPath2 */ Path2 = TRUE; else Path2 = FALSE; // ATE: if in this special cercumstance... our guys are moving on their own... // Stop sighting items // IN the future, we may want to do something else here... if ( gTacticalStatus.uiFlags & OUR_MERCS_AUTO_MOVE ) { itemsToo = FALSE; } for (maincnt = 0; maincnt < MAXVIEWPATHS; maincnt++) { marker = pSoldier->sGridNo; Blocking = FALSE; twoMoreTiles = FALSE; tilesLeftToSee = 99; fRevealItems = TRUE; fStopRevealingItemsAfterThisTile = FALSE; #ifdef _DEBUG if ( _KeyDown( NUM_LOCK ) ) { memset( gubFOVDebugInfoInfo, 0, sizeof( gubFOVDebugInfoInfo ) ); SetRenderFlags( RENDER_FLAG_FULL ); RenderWorld( ); } #endif for (markercnt = 0; markercnt < range; markercnt++) { //fGoneThroughDoor = FALSE; //fThroughWindow = FALSE; prevmarker = marker; nextDir = 99; fCheckForRooms = FALSE; fTravelCostObs = FALSE; if ( fStopRevealingItemsAfterThisTile ) { fRevealItems = FALSE; fStopRevealingItemsAfterThisTile = FALSE; } if (Path2) { markerDir = ViewPath2[maincnt][markercnt]; if (markercnt < 12) nextDir = ViewPath2[maincnt][markercnt+1]; } else { markerDir = ViewPath[maincnt][markercnt]; if (markercnt < 12) nextDir = ViewPath[maincnt][markercnt+1]; } // OK, check flags for going through door/window last tile if ( fThroughWindow == 1 ) { // ATE: Make sure we are going through the same direction! // THis is to solve the drassen SAM problem with seeing through walls if ( Dir[markerDir] == bThroughWindowDirection) { fThroughWindow = 2; } else { fThroughWindow = 0; } } else if ( fThroughWindow == 2 ) { // We've overstayed our welcome - remove! fThroughWindow = 0; } if ( fGoneThroughDoor == 1 ) { fGoneThroughDoor = 2; } else if ( fGoneThroughDoor == 2 ) { // We've overstayed our welcome - remove! fGoneThroughDoor = 0; } //ATE CHECK FOR NOVIEW! if ( nextDir == NOVIEW ) { nextDir = 99; } marker = NewGridNo(marker,(INT16)Inc[markerDir]); if ( marker == 12426 ) { int i = 0; } // End if this is a no view... if ( markerDir == NOVIEW && markercnt != 0 ) { break; } #ifdef _DEBUG if ( _KeyDown( NUM_LOCK ) ) { int cnt = GetJA2Clock( ); gubFOVDebugInfoInfo[ marker ] = (UINT8)markercnt; StartFrameBufferRender(); RenderFOVDebug( ); SetFont( LARGEFONT1 ); SetFontBackground( FONT_MCOLOR_BLACK ); SetFontForeground( FONT_MCOLOR_WHITE ); mprintf( 10, 10 , L"%d", maincnt ); //mprintf( 10, 20 , L"%d", marker ); //mprintf( 50, 20 , L"%d", pSoldier->sGridNo ); InvalidateScreen( ); EndFrameBufferRender(); RefreshScreen( NULL ); do { } while( ( GetJA2Clock( ) - cnt ) < 250 ); } #endif // Check if we can get to this gridno from our direction in ubMovementCost = gubWorldMovementCosts[ marker ][ Dir[ markerDir ] ][ ubLevel ]; // ATE: Added: If our current sector is below ground, ignore any blocks! if ( gfCaves && ubMovementCost != TRAVELCOST_CAVEWALL ) { ubMovementCost = TRAVELCOST_FLAT; } if ( IS_TRAVELCOST_DOOR( ubMovementCost ) ) { ubMovementCost = DoorTravelCost( pSoldier, marker, ubMovementCost, (BOOLEAN) (pSoldier->bTeam == gbPlayerNum), &iDoorGridNo ); pStructure = FindStructure( iDoorGridNo, STRUCTURE_ANYDOOR ); if ( pStructure != NULL && pStructure->fFlags & STRUCTURE_TRANSPARENT) { // cell door or somehow otherwise transparent; allow merc to see through ubMovementCost = TRAVELCOST_FLAT; } } // If we have hit an obstacle, STOP HERE if ( ubMovementCost >= TRAVELCOST_BLOCKED ) { // We have an obstacle here... // If it is bigger than a breadbox... err... taller than a man... // Then stop path altogether // otherwise just stop revealing items // CJC: only do this when the direction is horizontal; easier and faster to check // and the effect should still be good enough if ( ubMovementCost == TRAVELCOST_WALL || ubMovementCost == TRAVELCOST_DOOR || ubMovementCost == TRAVELCOST_EXITGRID ) { fTravelCostObs = TRUE; fRevealItems = FALSE; } else { // walls are handled above, so the blocking object is guaranteed not to be a wall bTallestStructureHeight = GetTallestStructureHeight( marker, FALSE ); if (bTallestStructureHeight >= 3) { fTravelCostObs = TRUE; fStopRevealingItemsAfterThisTile = TRUE; } else if ( bTallestStructureHeight != 0 ) { // stop revealing items after this tile but keep going fStopRevealingItemsAfterThisTile = TRUE; } } if ( (Dir[markerDir] % 2) == 1 ) { // diagonal fTravelCostObs = TRUE; // cheap hack... don't reveal items fRevealItems = FALSE; } else { bTallestStructureHeight = GetTallestStructureHeight( marker, FALSE ); if (bTallestStructureHeight >= 3) { fTravelCostObs = TRUE; fStopRevealingItemsAfterThisTile = TRUE; } else if ( bTallestStructureHeight != 0 ) { // stop revealing items after this tile but keep going fStopRevealingItemsAfterThisTile = TRUE; } } } // Check if it's been done already! if ( gubGridNoMarkers[ marker ] != gubGridNoValue ) { // Mark gridno gubGridNoMarkers[ marker ] = gubGridNoValue; // check and see if the gridno changed // if the gridno is the same, avoid redundancy and break if (marker==prevmarker && markercnt != 0 ) { } else // it changed { // Skip others if we have gone through a door but are too far away.... if ( fGoneThroughDoor ) { if (markercnt > 5 ) // Are we near the door? { break; } } // DO MINE FINDING STUFF // GET INDEX FOR ITEM HERE // if there IS a direction after this one, nextdir WILL NOT be 99 if (nextDir != 99) { Blocking = GetBlockingStructureInfo( marker, (INT8)Dir[ markerDir ], (INT8)Dir[ nextDir ], ubLevel, &bStructHeight, &pDummy, FALSE ); } else // no "next" direction, so pass in a NOWHERE so that // "SpecialViewObstruction" will know not to take it UINT32o consideration { Blocking = GetBlockingStructureInfo( marker, (INT8)Dir[markerDir], (INT8)30, ubLevel, &bStructHeight, &pDummy, FALSE ); } if ( gfCaves ) { Blocking = NOTHING_BLOCKING; } // CHECK FOR ROOMS if ( Blocking == BLOCKING_TOPLEFT_WINDOW || Blocking == BLOCKING_TOPLEFT_OPEN_WINDOW ) { // CHECK FACING DIRECTION! if ( Dir[markerDir] == NORTH || Dir[markerDir] == SOUTH ) { if (markercnt <= 1 ) // Are we right beside it? { fThroughWindow = TRUE; bThroughWindowDirection = ( INT8 ) Dir[ markerDir ]; } } } if ( Blocking == BLOCKING_TOPRIGHT_WINDOW || Blocking == BLOCKING_TOPRIGHT_OPEN_WINDOW ) { // CHECK FACING DIRECTION! if ( Dir[markerDir] == EAST || Dir[markerDir] == WEST ) { if (markercnt <= 1 ) // Are we right beside it? { fThroughWindow = TRUE; bThroughWindowDirection = ( INT8 ) Dir[ markerDir ]; } } } if ( Blocking == BLOCKING_TOPLEFT_DOOR ) { fGoneThroughDoor = TRUE; } if ( Blocking == BLOCKING_TOPRIGHT_DOOR ) { fGoneThroughDoor = TRUE; } // ATE: If we hit this tile, find item always! //if (Blocking < FULL_BLOCKING ) { // Handle special things for our mercs, like uncovering roofs // and revealing objects... //gpSoldier->shad |= SEENBIT; //itemVisible = ObjList[itemIndex].visible; // NOTE: don't allow object viewing if gassed XXX if (itemsToo && fRevealItems ) // && itemIndex < MAXOBJECTLIST) { // OK, look for corpses... LookForAndMayCommentOnSeeingCorpse( pSoldier, marker, ubLevel ); if ( GetItemPool( marker, &pItemPool, ubLevel ) ) { itemVisible = pItemPool->bVisible; if ( SetItemPoolVisibilityOn( pItemPool, INVISIBLE, fShowLocators ) ) { SetRenderFlags(RENDER_FLAG_FULL); // WANNE: Should we pause when item was found in tactical? bool enableItemSpottingAction = true; if ( !is_networked && gGameExternalOptions.fItemSpottedNoTalk && gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT) enableItemSpottingAction = false; if (enableItemSpottingAction) { if ( fShowLocators ) { // Set makred render flags //gpWorldLevelData[marker].uiFlags|=MAPELEMENT_REDRAW; //gpWorldLevelData[gusCurMousePos].pTopmostHead->uiFlags |= LEVELNODE_DYNAMIC; //SetRenderFlags(RENDER_FLAG_MARKED); SetRenderFlags(RENDER_FLAG_FULL); // Hault soldier // ATE: Only if in combat... if ( gTacticalStatus.uiFlags & INCOMBAT ) { pSoldier->HaultSoldierFromSighting( FALSE ); } else { // ATE: Make sure we show locators... gTacticalStatus.fLockItemLocators = FALSE; } if ( !fItemsQuoteSaid && gTacticalStatus.fLockItemLocators == FALSE ) { gTacticalStatus.fLockItemLocators = TRUE; if ( gTacticalStatus.ubAttackBusyCount > 0 && ( gTacticalStatus.uiFlags & INCOMBAT ) ) { gTacticalStatus.fItemsSeenOnAttack = TRUE; gTacticalStatus.ubItemsSeenOnAttackSoldier = pSoldier->ubID; gTacticalStatus.usItemsSeenOnAttackGridNo = marker; } else { // Display quote! if ( !AM_AN_EPC( pSoldier ) ) { TacticalCharacterDialogueWithSpecialEvent( pSoldier, (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, marker, 0 ); } else { // Turn off item lock for locators... gTacticalStatus.fLockItemLocators = FALSE; // Slide to location! SlideToLocation( 0, marker ); } } fItemsQuoteSaid = TRUE; } } } } } } // if blood here, let the user see it now... //if (ExtGrid[marker].patrolInfo < MAXBLOOD) // gpSoldier->blood = ExtGrid[marker].patrolInfo; //DoRoofs(marker,gpSoldier); tilesLeftToSee--; } // CHECK FOR HIDDEN STRUCTS // IF we had a hidden struct here that is not visible ( which will still be true because // we set it revealed below... if ( DoesGridNoContainHiddenStruct( marker, &fHiddenStructVisible ) ) { if ( !fHiddenStructVisible ) { gpWorldLevelData[marker].uiFlags|=MAPELEMENT_REDRAW; SetRenderFlags(RENDER_FLAG_MARKED); RecompileLocalMovementCosts( marker ); } } if (tilesLeftToSee <= 0) break; if ( Blocking == FULL_BLOCKING || ( fTravelCostObs && !fThroughWindow ) ) { break; } //if ( Blocking == NOTHING_BLOCKING || Blocking == BLOCKING_NEXT_TILE ) if ( Blocking == NOTHING_BLOCKING ) { fCheckForRooms = TRUE; } if ( ubLevel != 0 ) { fCheckForRooms = FALSE; } // CHECK FOR SLANT ROOF! { STRUCTURE *pStructure, *pBase; pStructure = FindStructure( marker, STRUCTURE_SLANTED_ROOF ); if ( pStructure != NULL ) { pBase = FindBaseStructure( pStructure ); // ADD TO SLANTED ROOF LIST! AddSlantRoofFOVSlot( marker ); } } // Set gridno as revealed if ( ubLevel == FIRST_LEVEL ) { if ( gfBasement || gfCaves ) { // OK, if we are underground, we don't want to reveal stuff if // 1 ) there is a roof over us and // 2 ) we are not in a room if ( gusWorldRoomInfo[ marker ] == NO_ROOM && TypeRangeExistsInRoofLayer( marker, FIRSTROOF, FOURTHROOF, &usIndex ) ) { int i = 0; } else { gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED; if( gfCaves ) { RemoveFogFromGridNo( marker ); } } } else { gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED; } // CHECK FOR ROOMS //if ( fCheckForRooms ) { if ( InAHiddenRoom( marker, &usRoomNo ) ) { RemoveRoomRoof( marker, usRoomNo, pSoldier ); if ( usRoomNo == ROOM_SURROUNDING_BOXING_RING && gWorldSectorX == BOXING_SECTOR_X && gWorldSectorY == BOXING_SECTOR_Y && gbWorldSectorZ == BOXING_SECTOR_Z ) { // reveal boxing ring at same time RemoveRoomRoof( marker, BOXING_RING, pSoldier ); } } } } else { gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_REVEALED_ROOF; } // Check for blood.... UpdateBloodGraphics( marker, ubLevel ); if ( Blocking != NOTHING_BLOCKING && Blocking != BLOCKING_TOPLEFT_DOOR && Blocking != BLOCKING_TOPRIGHT_DOOR && Blocking != BLOCKING_TOPLEFT_WINDOW && Blocking != BLOCKING_TOPRIGHT_WINDOW && Blocking != BLOCKING_TOPRIGHT_OPEN_WINDOW && Blocking != BLOCKING_TOPLEFT_OPEN_WINDOW) { break; } //gpWorldLevelData[ marker ].uiFlags |= MAPELEMENT_SHADELAND; } } // End of duplicate check else { if ( fTravelCostObs ) { break; } } } // end of one path } // end of path loop // Loop through all availible slant roofs we collected and perform cool stuff on them ExamineSlantRoofFOVSlots( ); //pSoldier->needToLookForItems = FALSE; //LookForDoors(pSoldier,UNAWARE); }
// 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 FindOutIfAnyMercAboutToLeaveIsGonnaRenew( void ) { // find out is something was said SOLDIERTYPE *pSoldier = NULL, *pSoldierWhoWillQuit = NULL; INT32 iCounter= 0, iNumberOnTeam = 0; // WDS - make number of mercenaries, etc. be configurable UINT8 ubPotentialMercs[ CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS ] = { 0 }; UINT8 ubNumMercs = 0; UINT8 ubChosenMerc; gfFirstMercSayQuote = FALSE; pSoldier = &Menptr[ 0 ]; iNumberOnTeam =gTacticalStatus.Team[ OUR_TEAM ].bLastID; // run through list of grunts whoose contract are up in the next 2 hours // ATE: AND - build list THEN choose one! // What we will do here is make a list of mercs that will want // to stay if offered. Durning that process, also check if there // is any merc that does not want to stay and only display that quote // if they are the only one here.... for( iCounter = 0; iCounter < iNumberOnTeam; iCounter++ ) { pSoldier = &Menptr[ iCounter ]; // valid soldier? if( ( pSoldier->bActive == FALSE ) || ( pSoldier->stats.bLife == 0 ) || ( pSoldier->bAssignment == IN_TRANSIT ) ||( pSoldier->bAssignment == ASSIGNMENT_POW ) ) { // no continue; } if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC ) { //if the user hasnt renewed yet, and is still leaving today if ( ContractIsGoingToExpireSoon( pSoldier ) ) { // OK, default value for quote said pSoldier->ubContractRenewalQuoteCode = SOLDIER_CONTRACT_RENEW_QUOTE_NOT_USED; // Add this guy to the renewal list ContractRenewalList[ ubNumContractRenewals ].ubProfileID = pSoldier->ubProfile; ubNumContractRenewals++; if( WillMercRenew( pSoldier, FALSE ) ) { ubPotentialMercs[ ubNumMercs ] = pSoldier->ubID; ubNumMercs++; } else { pSoldierWhoWillQuit = pSoldier; } // Add to list! AddSoldierToWaitingListQueue( pSoldier ); } } else { if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC ) { // Do nothing here for now... } } } // OK, check if we should display line for the guy who does not want // to stay if ( ubNumMercs == 0 && pSoldierWhoWillQuit != NULL ) { // OK, he does not want to renew....... HandleImportantMercQuote( pSoldierWhoWillQuit, QUOTE_MERC_LEAVING_ALSUCO_SOON ); AddReasonToWaitingListQueue( CONTRACT_EXPIRE_WARNING_REASON ); TacticalCharacterDialogueWithSpecialEvent( pSoldierWhoWillQuit, 0, DIALOGUE_SPECIAL_EVENT_SHOW_UPDATE_MENU, 0,0 ); pSoldierWhoWillQuit->ubContractRenewalQuoteCode = SOLDIER_CONTRACT_RENEW_QUOTE_115_USED; } else { // OK, pick one.... if ( ubNumMercs > 0 ) { ubChosenMerc = (UINT8)Random( ubNumMercs ); SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,1 ,MAP_SCREEN ,0 ,0 ,0 ); HandleImportantMercQuote( MercPtrs[ ubPotentialMercs[ ubChosenMerc ] ], QUOTE_CONTRACTS_OVER ); SpecialCharacterDialogueEvent( DIALOGUE_SPECIAL_EVENT_LOCK_INTERFACE,0 ,MAP_SCREEN ,0 ,0 ,0 ); AddReasonToWaitingListQueue( CONTRACT_EXPIRE_WARNING_REASON ); TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ ubPotentialMercs[ ubChosenMerc ] ], 0, DIALOGUE_SPECIAL_EVENT_SHOW_UPDATE_MENU, 0,0 ); MercPtrs[ ubPotentialMercs[ ubChosenMerc ] ]->ubContractRenewalQuoteCode = SOLDIER_CONTRACT_RENEW_QUOTE_89_USED; } } }
void UpdateBuddyAndHatedCounters( void ) { INT8 bMercID; INT32 iLoop; INT8 bOtherID; INT8 bLastTeamID; UINT8 ubOtherProfileID; SOLDIERTYPE *pSoldier; SOLDIERTYPE *pOtherSoldier; MERCPROFILESTRUCT *pProfile; BOOLEAN fSameGroupOnly; BOOLEAN fUpdatedTimeTillNextHatedComplaint = FALSE; bMercID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID; //loop though all the mercs for ( pSoldier = MercPtrs[ bMercID ]; bMercID <= bLastTeamID; bMercID++,pSoldier++) { fSameGroupOnly = FALSE; //if the merc is active and on a combat assignment if ( pSoldier->bActive && pSoldier->bAssignment < ON_DUTY ) { pProfile = &(gMercProfiles[ pSoldier->ubProfile ]); // if we're moving, we only check vs other people in our squad if (pSoldier->ubGroupID != 0 && PlayerIDGroupInMotion( pSoldier->ubGroupID )) { fSameGroupOnly = TRUE; } fUpdatedTimeTillNextHatedComplaint = FALSE; bOtherID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; for ( pOtherSoldier = MercPtrs[ bOtherID ]; bOtherID <= bLastTeamID; bOtherID++, pOtherSoldier++) { // is this guy in the same sector and on active duty (or in the same moving group) if (bOtherID != bMercID && pOtherSoldier->bActive && pOtherSoldier->bAssignment < ON_DUTY ) { if (fSameGroupOnly) { // all we have to check is the group ID if (pSoldier->ubGroupID != pOtherSoldier->ubGroupID) { continue; } } else { // check to see if the location is the same if (pOtherSoldier->sSectorX != pSoldier->sSectorX || pOtherSoldier->sSectorY != pSoldier->sSectorY || pOtherSoldier->bSectorZ != pSoldier->bSectorZ) { continue; } // if the OTHER soldier is in motion then we don't do anything! if (pOtherSoldier->ubGroupID != 0 && PlayerIDGroupInMotion( pOtherSoldier->ubGroupID )) { continue; } } ubOtherProfileID = pOtherSoldier->ubProfile; for ( iLoop = 0; iLoop < 4; iLoop++ ) { switch( iLoop ) { case 0: case 1: if (pProfile->bHated[iLoop] == ubOtherProfileID) { // arrgs, we're on assignment with the person we loathe! if ( pProfile->bHatedCount[iLoop] > 0 ) { pProfile->bHatedCount[iLoop]--; if ( pProfile->bHatedCount[iLoop] == 0 && pSoldier->bInSector && gTacticalStatus.fEnemyInSector ) { // just reduced count to 0 but we have enemy in sector... pProfile->bHatedCount[iLoop] = 1; } else if (pProfile->bHatedCount[iLoop] > 0 && (pProfile->bHatedCount[iLoop] == pProfile->bHatedTime[iLoop] / 2 || ( pProfile->bHatedCount[iLoop] < pProfile->bHatedTime[iLoop] / 2 && pProfile->bHatedCount[iLoop] % TIME_BETWEEN_HATED_COMPLAINTS == 0 ) ) ) { // complain! if (iLoop == 0) { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_ONE ); } else { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO ); } StopTimeCompression(); } else if ( pProfile->bHatedCount[iLoop] == 0 ) { // zero count! if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC || pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC ) { // MERC mercs leave now! if (iLoop == 0) { TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED1 ); } else { TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED2 ); } // Leave now! ( handle equipment too ).... TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING, 0,0 ); pSoldier->ubLeaveHistoryCode = HISTORY_MERC_QUIT; } else { // complain! if (iLoop == 0) { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_ONE ); } else { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO ); } pProfile->ubTimeTillNextHatedComplaint = TIME_BETWEEN_HATED_COMPLAINTS - 1; } } } else { // if we haven't updated the time till our next complaint, do so // if it's 0, gripe. if ( !fUpdatedTimeTillNextHatedComplaint ) { if ( pProfile->ubTimeTillNextHatedComplaint == 0 ) { pProfile->ubTimeTillNextHatedComplaint = TIME_BETWEEN_HATED_COMPLAINTS - 1; } else { pProfile->ubTimeTillNextHatedComplaint--; } fUpdatedTimeTillNextHatedComplaint = TRUE; } if ( pProfile->ubTimeTillNextHatedComplaint == 0 ) { // complain! if (iLoop == 0) { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_ONE ); } else { TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO ); } } } } break; case 2: if (pProfile->bLearnToHate == ubOtherProfileID) { if ( pProfile->bLearnToHateCount > 0 ) { pProfile->bLearnToHateCount--; if ( pProfile->bLearnToHateCount == 0 && pSoldier->bInSector && gTacticalStatus.fEnemyInSector ) { // just reduced count to 0 but we have enemy in sector... pProfile->bLearnToHateCount = 1; } else if (pProfile->bLearnToHateCount > 0 && (pProfile->bLearnToHateCount == pProfile->bLearnToHateTime / 2 || pProfile->bLearnToHateCount < pProfile->bLearnToHateTime / 2 && pProfile->bLearnToHateCount % TIME_BETWEEN_HATED_COMPLAINTS == 0 ) ) { // complain! TacticalCharacterDialogue( pSoldier, QUOTE_LEARNED_TO_HATE_MERC ); StopTimeCompression(); } else if (pProfile->bLearnToHateCount == 0) { // set as bHated[2]; pProfile->bHated[2] = pProfile->bLearnToHate; pProfile->bMercOpinion[ubOtherProfileID] = HATED_OPINION; if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC || (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC && (pSoldier->ubProfile == DEVIN || pSoldier->ubProfile == SLAY || pSoldier->ubProfile == IGGY || pSoldier->ubProfile == CONRAD ) ) ) { // Leave now! ( handle equipment too ).... TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_LEARN_TO_HATE ); TacticalCharacterDialogueWithSpecialEvent( pSoldier, 0, DIALOGUE_SPECIAL_EVENT_CONTRACT_ENDING, 0,0 ); pSoldier->ubLeaveHistoryCode = HISTORY_MERC_QUIT; } else if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC) { // whine again TacticalCharacterDialogue( pSoldier, QUOTE_LEARNED_TO_HATE_MERC ); } } if (pProfile->bLearnToHateCount < pProfile->bLearnToHateTime / 2) { // gradual opinion drop pProfile->bMercOpinion[ubOtherProfileID] += (HATED_OPINION - pProfile->bMercOpinion[ubOtherProfileID]) / (pProfile->bLearnToHateCount + 1); } } else { if ( !fUpdatedTimeTillNextHatedComplaint ) { if ( pProfile->ubTimeTillNextHatedComplaint == 0 ) { pProfile->ubTimeTillNextHatedComplaint = TIME_BETWEEN_HATED_COMPLAINTS - 1; } else { pProfile->ubTimeTillNextHatedComplaint--; } fUpdatedTimeTillNextHatedComplaint = TRUE; } if ( pProfile->ubTimeTillNextHatedComplaint == 0 ) { // complain! TacticalCharacterDialogue( pSoldier, QUOTE_LEARNED_TO_HATE_MERC ); } } } break; case 3: if (pProfile->bLearnToLikeCount > 0 && pProfile->bLearnToLike == ubOtherProfileID) { pProfile->bLearnToLikeCount--; if (pProfile->bLearnToLikeCount == 0) { // add to liked! pProfile->bBuddy[2] = pProfile->bLearnToLike; pProfile->bMercOpinion[ubOtherProfileID] = BUDDY_OPINION; } else if (pProfile->bLearnToLikeCount < pProfile->bLearnToLikeTime / 2) { // increase opinion of them! pProfile->bMercOpinion[ubOtherProfileID] += (BUDDY_OPINION - pProfile->bMercOpinion[ubOtherProfileID]) / (pProfile->bLearnToLikeCount + 1); break; } } break; } } } } } } }