Files
source/Strategic/Strategic Merc Handler.cpp
T
Wanne d5b4599e9c New Trait: Snitch (Trait 22) (by anv)
Every midnight snitches will give you a report about their collegues' opinions. Information includes:
- merc whining about high death rate,
- merc whining about player reputation,
- merc whining about his low morale,
- merc whining about some other merc (unliked, not only hated),
- merc planning to quit (leave without renewing contract, only AIM mercs) next day,
- merc whining about player inactivity,
- merc whining about player owing them money (you can only owe money to MERC mercs).

List of snitches (trait 22)
Beth
Bud
Buzz
Carp
Ears
Gary
Hurl
Lance
Leon
Weasel

see: http://www.bears-pit.com/board/ubbthreads.php/topics/329412/Snitches_+_Externalised_morale.html

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6723 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2014-01-01 12:02:23 +00:00

1564 lines
50 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Strategic All.h"
#else
#include "Types.h"
#include "Strategic Merc Handler.h"
#include "History.h"
#include "Game clock.h"
#include "insurance Contract.h"
#include "Soldier Profile.h"
#include "Game Event Hook.h"
#include "Assignments.h"
#include "Overhead.h"
#include "Merc Contract.h"
#include "Merc Hiring.h"
#include "Dialogue Control.h"
#include "Random.h"
#include "Morale.h"
#include "Mercs.h"
#include "Mapscreen.h"
#include "weapons.h"
#include "Personnel.h"
#include "Strategic Movement.h"
#include "LaptopSave.h"
#include "Message.h"
#include "Text.h"
#include "Interface.h"
#include "strategic.h"
#include "strategicmap.h"
#include "Strategic Status.h"
#include "aim.h"
#include "email.h"
#include "Map Screen Interface.h"
#include "Campaign.h"
#include "Soldier Add.h"
#include "screenids.h"
#include "gameloop.h"
#include "jascreens.h"
#include "Soldier macros.h"
#include "finances.h"
#include "GameSettings.h"
#include "Quests.h"
// HEADROCK HAM B1: Additional Include for Dynamic Roaming Restrictions
#include "MilitiaSquads.h"
// HEADROCK HAM 3.6: Additional include for Facility Operating Deby
#include "Facilities.h"
// HEADROCK HAM 3.6: And another include, for militia upkeep costs.
#include "Town Militia.h"
#endif
#ifdef JA2UB
#include "ub_config.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
#define NUM_DAYS_TILL_UNPAID_RPC_QUITS 3
// can you say me too after someone has said thier contract about to end
BOOLEAN fContractOverMeTooFlag = FALSE;
BOOLEAN fContractOverAndIWontRenewMeTooFlag = FALSE;
BOOLEAN fProcessingAMerc = FALSE;
SOLDIERTYPE *pProcessingSoldier = NULL;
extern BOOLEAN gfFirstMercSayingQuoteWillLeaveNoMatterWhat = FALSE;
// build a list of mercs based on departure time
void BuildMercQuitList( SOLDIERTYPE *pMercList );
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->flags.uiStatusFlags |= SOLDIER_DEAD;
// Set breath to 0!
pSoldier->bBreathMax = pSoldier->bBreath = 0;
// not asleep, DEAD!
pSoldier->flags.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 );
}
// 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;
//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 ].bDisability )
{
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;
//handle Slay differently if SlayForever is enabled
if( pSoldier->ubProfile == SLAY && gGameExternalOptions.fEnableSlayForever == TRUE)
{
}
//if the character is an RPC
//else if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
//new profiles by Jazz
else if ( gProfilesRPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile )
{
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 );
}
}
}
}
}
// WANNE: Only send mails from the original 1.13 merc, and not from the wildfire merc,
// otherwise we get wrong mails cause of hardcoded Email.edt structure!!!!!
UINT16 numOriginalProfiles = 255;
for( cnt = 0; cnt < numOriginalProfiles; 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( IsProfileIdAnAimOrMERCMerc( (UINT8)cnt ) )
{
// 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
//Kaiden: Externalized if Mercs get killed
if (gGameExternalOptions.gfMercsDieOnAssignment)
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;
#ifdef JA2UB
//if the Laptop is NOT broken
if( gubQuest[ QUEST_FIX_LAPTOP ] != QUESTINPROGRESS && gGameUBOptions.LaptopQuestEnabled == TRUE )
{
#endif
// Read from EmailMercAvailable.xml
UINT8 pMerc = 0;
UINT8 iMerc = 0;
UINT8 oMerc = 0;
if ( ReadXMLEmail == TRUE )
{
oMerc = cnt;
iMerc = oMerc * 1;
if ( oMerc != 0 )
pMerc = oMerc + 1;
else
pMerc = 0;
if ( gProfilesAIM[cnt].ProfilId == cnt )
AddEmailTypeXML( pMerc, iMerc, iMerc, GetWorldTotalMin(), -1 , TYPE_EMAIL_AIM_AVAILABLE);
}
else
{
// Read from Email.edt and sender (nickname) from MercProfiles.xml
if (cnt < 170)
{
// 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) cnt, GetWorldTotalMin(), -1, -1 , TYPE_EMAIL_EMAIL_EDT_NAME_MERC);
}
else
{
// Wildfire mercs
if (cnt < 178)
{
UINT16 iMsgLength = cnt;
// Fake Barry Unger mail, but with the msgLength of the WF merc ID -> Correct in PreProcessEmail()
AddEmailWFMercAvailable( ( UINT8 )( iOffset + 0 * AIM_REPLY_LENGTH_BARRY ), iMsgLength, cnt, GetWorldTotalMin(), -1 , TYPE_EMAIL_EMAIL_EDT_NAME_MERC);
}
// Generic mail
else
{
// TODO.RW: Send generic mail
UINT16 iMsgLength = cnt;
// Fake Barry Unger mail, but with the msgLength of the WF merc ID -> Correct in PreProcessEmail()
AddEmailWFMercAvailable( ( UINT8 )( iOffset + 0 * AIM_REPLY_LENGTH_BARRY ), iMsgLength, cnt, GetWorldTotalMin(), -1 , TYPE_EMAIL_EMAIL_EDT_NAME_MERC);
}
}
}
// WANNE: Should we stop time compression. I don't know.
//StopTimeCompression();
#ifdef JA2UB
}
#endif
}
}
}
}
else // was already available today
{
// if it's an AIM or M.E.R.C. merc
if( IsProfileIdAnAimOrMERCMerc( (UINT8)cnt ) )
{
// check to see if he goes on another assignment
//if (cnt < MAX_NUMBER_MERCS)
if ( gProfilesAIM[ cnt ].ProfilId == cnt ) //new profiles by Jazz
{
// 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 if ( gProfilesMERC[ cnt ].ProfilId == cnt ) //new profiles by Jazz
{
// 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;
}
}
// tais: disable mercs being on assignment
if (Random(100) < uiChance && gGameExternalOptions.fMercsOnAssignment < 2)
{
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 );
#ifdef JA2UB
//no UB
#else
HandleSlayDailyEvent( );
#endif
// rebuild list for mapscreen
ReBuildCharactersList( );
// HEADROCK HAM B1: Run a function to redefine Roaming Militia Restrictions.
if (gGameExternalOptions.fDynamicRestrictRoaming)
{
// HEADROCK HAM 5: New flag tells us to also recheck restriced sectors.
AdjustRoamingRestrictions( FALSE );
}
// HEADROCK HAM 3.6: Pay debt for operating Facilities today. If can't be paid, apply loyalty hit.
if (giTotalOwedForFacilityOperationsToday)
{
HandleDailyPaymentFacilityDebt();
}
// HEADROCK HAM 3.6: Pay for militia upkeep
HandleMilitiaUpkeepPayment();
// anv: time for snitches to report
HandleSnitchCheck();
}
/*
void BuildMercQuitList( SOLDIERTYPE *pMercList )
{
// go through list of mercs on players team, fill pMercList sorted from most recent leave time, to furthest leave time
INT32 cnt;
INT8 bLastTeamID;
SOLDIERTYPE *pSoldier;
INT32 iCounter = 0;
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
//loop though all the mercs
for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++, iCounter++ )
{
if ( pSoldier->bActive )
{
// copy to list
pMercList[ iCounter ] = pSoldier;
}
}
// now sort based on departure time..simple bubble sort
for( cnt = 0; cnt <=iCounter; cnt++ )
{
for( cntB = 0; cntB <=iCounter; cntB++ )
{
if( MercPtrs[ cntB ]->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( MercPtrs[ cntB ] ) )
{
// swap
pSoldier = MercPtrs[ cntB ];
MercPtrs[ cntB ] = MercPtrs[ cnt ];
MercPtrs[ cnt ] = pSoldier;
}
}
}
else if( MercPtrs[ cntB ]->ubWhatKindOfMercAmI == MERC_TYPE__AIM )
{
if( MercPtrs[ cntB ]->iEndofContractTime < MercPtrs[ cnt ]->iEndofContractTime )
{
// swap
pSoldier = MercPtrs[ cntB ];
MercPtrs[ cntB ] = MercPtrs[ cnt ];
MercPtrs[ cnt ] = pSoldier;
}
}
else
{
// not a hirable guy, move to the botton
pSoldier = MercPtrs[ cnt ];
MercPtrs[ cnt ] = MercPtrs[ cntB ];
MercPtrs[ cntB ] = pSoldier;
}
}
}
return;
}
*/
/*
void HandleMercsAboutToLeave( SOLDIERTYPE *pMercList )
{
// run from top of list to bottom..if merc is gonna leave within a defined time frame of the previous guy and they are leaving the same day (today)
// then post then with the quote at the same time
for( iCounter = 0; iCounter < 21; iCounter++ )
{
if( iCounter == 0 )
{
// first guy, if he no leave today, no one is leave, go home
if( ( pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__MERC ) && ( pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__AIM ) )
{
return;
}
else
{
if( ( pSoldier->iEndofContractTime / 1440 ) > (INT32)GetWorldDay( ) )
{
return;
}
else
{
//if the soldier is alive anc concious
if( IsTheSoldierAliveAndConcious( pSoldier ) )
{
//if the soldier is an AIM merc
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
{
//add an event so the merc will say the departing warning ( 2 hours prior to leaving
AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE_COMMENT, MERC_DEPARTURE_TIME_OF_DAY - 2 * 60, (UINT32) pSoldier->ubID );
}
else
{
// merc merc, they'll just leave
}
}
}
}
}
}
*/
// 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;
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;
}
}
// ATE: Called for RPCs who should now complain about no pay...
void RPCWhineAboutNoPay( UINT8 ubID )
{
SOLDIERTYPE *pSoldier;
pSoldier = &Menptr[ ubID ];
//if the soldier was removed before getting into this function, return
if( !pSoldier->bActive )
return;
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC )
{
// Say quote for needing pay!
TacticalCharacterDialogue( pSoldier, QUOTE_NOT_GETTING_PAID );
}
}
// OK loop through and check!
BOOLEAN SoldierHasWorseEquipmentThanUsedTo( SOLDIERTYPE *pSoldier )
{
UINT16 usItem;
INT32 bBestArmour = -1;
INT32 bBestArmourIndex = -1;
INT32 bBestGun = -1;
INT32 bBestGunIndex = -1;
for ( UINT32 cnt = 0; cnt < pSoldier->inv.size(); cnt++ )
{
// Look for best gun/armour
if ( pSoldier->inv[cnt].exists() == true )
{
usItem = pSoldier->inv[ cnt ].usItem;
// Check if it's a gun
if ( Item[ usItem ].usItemClass & IC_GUN )
{
if ( Weapon[ usItem ].ubDeadliness > bBestGun )
{
bBestGunIndex = (INT8)cnt;
bBestGun = Weapon[ usItem ].ubDeadliness;
}
}
// If it's armour
if ( Item[ usItem ].usItemClass & IC_ARMOUR )
{
if ( Armour[ Item[ usItem ].ubClassIndex ].ubProtection > bBestArmour )
{
bBestArmourIndex = (INT8)cnt;
bBestArmour = min(128,Armour[ Item[ usItem ].ubClassIndex ].ubProtection);
}
}
}
}
// Modify these values based on morale - lower opinion of equipment if morale low, increase if high
// this of course assumes default morale is 50
if ( bBestGun != -1 )
{
bBestGun = (bBestGun * (50 + pSoldier->aiData.bMorale)) / 100;
}
if ( bBestArmour != -1 )
{
bBestArmour = (bBestArmour * (50 + pSoldier->aiData.bMorale)) / 100;
}
// OK, check values!
if ( (bBestGun != -1 && bBestGun < ( gMercProfiles[ pSoldier->ubProfile ].bMainGunAttractiveness / 2 )) ||
(bBestArmour != -1 && bBestArmour < ( gMercProfiles[ pSoldier->ubProfile ].bArmourAttractiveness / 2 )) )
{
// Pipe up!
return( TRUE );
}
return( FALSE );
}
void MercComplainAboutEquipment( UINT8 ubProfile )
{
SOLDIERTYPE *pSoldier;
if ( ubProfile == LARRY_NORMAL )
{
if ( CheckFact( FACT_LARRY_CHANGED, 0 ) )
{
ubProfile = LARRY_DRUNK;
}
}
else if ( ubProfile == LARRY_DRUNK )
{
if ( CheckFact( FACT_LARRY_CHANGED, 0 ) == FALSE )
{
ubProfile = LARRY_NORMAL;
}
}
// Are we dead/ does merc still exist?
pSoldier = FindSoldierByProfileID( ubProfile, FALSE );
if ( pSoldier != NULL )
{
if ( pSoldier->stats.bLife >= OKLIFE && pSoldier->flags.fMercAsleep != TRUE && pSoldier->bAssignment < ON_DUTY )
{
//ATE: Double check that this problem still exists!
if ( SoldierHasWorseEquipmentThanUsedTo( pSoldier ) )
{
// Say quote!
TacticalCharacterDialogue( pSoldier, QUOTE_WHINE_EQUIPMENT );
// anv: morale hit
HandleMoraleEvent( pSoldier, MORALE_BAD_EQUIPMENT, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
ModifyPlayerReputation(REPUTATION_TOWN_LOST);
}
}
}
}
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 < 7; iLoop++ )
{
switch( iLoop )
{
case 0:
case 1:
case 2:
case 3:
case 4:
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 if (iLoop == 1)
{
TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO );
}
else if (iLoop == 2)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_THREE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_THREE );
}
else if (iLoop == 3)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FOUR );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FOUR );
}
else if (iLoop == 4)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FIVE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FIVE );
}
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 if (iLoop == 1)
{
TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED2 );
}
else if (iLoop == 2)
{
TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED3 );
}
else if (iLoop == 3)
{
TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED4 );
}
else if (iLoop == 4)
{
TacticalCharacterDialogue( pSoldier, QUOTE_MERC_QUIT_HATED5 );
}
// 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 if (iLoop == 1)
{
TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO );
}
else if (iLoop == 2)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_THREE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_THREE );
}
else if (iLoop == 3)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FOUR );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FOUR );
}
else if (iLoop == 4)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FIVE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FIVE );
}
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 if (iLoop == 1)
{
TacticalCharacterDialogue( pSoldier, QUOTE_HATED_MERC_TWO );
}
else if (iLoop == 2)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_THREE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_THREE );
}
else if (iLoop == 3)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FOUR );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FOUR );
}
else if (iLoop == 4)
{
if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__AIM_MERC )
TacticalCharacterDialogue( pSoldier, QUOTE_AIM_HATED_MERC_FIVE );
else
TacticalCharacterDialogue( pSoldier, QUOTE_NON_AIM_HATED_MERC_FIVE );
}
}
}
}
break;
case 5:
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];
// anv: nope, we don't want to overwrite possible standard foe, instead added extra check to WhichHated(), CanMercBeHired()
if (OKToCheckOpinion(ubOtherProfileID)) {
//pProfile->bHated[2] = pProfile->bLearnToHate;
pProfile->bMercOpinion[ubOtherProfileID] = HATED_OPINION;
}
#ifdef JA2UB
if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC || (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC && ( /* pSoldier->ubProfile == DEVIN || */ pSoldier->ubProfile == SLAY || pSoldier->ubProfile == IGGY || pSoldier->ubProfile == CONRAD ) ) )
#else
if (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC || (pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__NPC && (pSoldier->ubProfile == DEVIN || pSoldier->ubProfile == SLAY || pSoldier->ubProfile == IGGY || pSoldier->ubProfile == CONRAD ) ) )
#endif
{
// 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
if (OKToCheckOpinion(ubOtherProfileID)) {
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 6:
if (pProfile->bLearnToLikeCount > 0 && pProfile->bLearnToLike == ubOtherProfileID)
{
pProfile->bLearnToLikeCount--;
if (pProfile->bLearnToLikeCount == 0)
{
// add to liked!
// anv: nope, we don't want to overwrite possible standard buddy, instead added extra check to WhichBuddy(), DoesMercHaveABuddyOnTheTeam(), CanMercBeHired()
if (OKToCheckOpinion(ubOtherProfileID)) {
//pProfile->bBuddy[2] = pProfile->bLearnToLike;
pProfile->bMercOpinion[ubOtherProfileID] = BUDDY_OPINION;
}
}
else if (pProfile->bLearnToLikeCount < pProfile->bLearnToLikeTime / 2)
{
// increase opinion of them!
if (OKToCheckOpinion(ubOtherProfileID)) {
pProfile->bMercOpinion[ubOtherProfileID] += (BUDDY_OPINION - pProfile->bMercOpinion[ubOtherProfileID]) / (pProfile->bLearnToLikeCount + 1);
}
break;
}
}
break;
}
}
}
}
}
}
}
void HourlyCamouflageUpdate( void )
{
INT8 bMercID, bLastTeamID;
SOLDIERTYPE * pSoldier;
BOOLEAN camoWoreOff = FALSE;
bMercID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
// loop through all mercs
for ( pSoldier = MercPtrs[ bMercID ]; bMercID <= bLastTeamID; bMercID++,pSoldier++)
{
if ( pSoldier->bActive )
{
// SANDRO - new Ranger trait reduces camo degrading, which replaces camouflage trait
// may be a little awkward solution with chances, but can work
if (gGameOptions.fNewTraitSystem)
{
if( pSoldier->bCamo > 0 )
{
// first limit camo to valid values
pSoldier->bCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->bCamo );
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
// pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->bCamo -= 1; // 2
if (pSoldier->bCamo <= 0)
{
pSoldier->bCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->urbanCamo > 0 )
{
// first limit camo to valid values
pSoldier->urbanCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->urbanCamo );
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
// pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->urbanCamo -= 1; // 2
if (pSoldier->urbanCamo <= 0)
{
pSoldier->urbanCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->desertCamo > 0 )
{
// first limit camo to valid values
pSoldier->desertCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->desertCamo );
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
// pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->desertCamo -= 1; // 2
if (pSoldier->desertCamo <= 0)
{
pSoldier->desertCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->snowCamo > 0 )
{
// first limit camo to valid values
pSoldier->snowCamo = __min( gGameExternalOptions.bCamoKitArea, pSoldier->snowCamo );
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
// pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->snowCamo -= 1; // 2
if (pSoldier->snowCamo <= 0)
{
pSoldier->snowCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
else
{
// if the merc has non-zero camo, degrade it by 1%
// SANDRO - different types of Camouflaged trait have been merged together
if( ( pSoldier->bCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->bCamo -= 1; // 2
if (pSoldier->bCamo <= 0)
{
pSoldier->bCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( ( pSoldier->urbanCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->urbanCamo -= 1; // 2
if (pSoldier->urbanCamo <= 0)
{
pSoldier->urbanCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( ( pSoldier->desertCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->desertCamo -= 1; // 2
if (pSoldier->desertCamo <= 0)
{
pSoldier->desertCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( ( pSoldier->snowCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->snowCamo -= 1; // 2
if (pSoldier->snowCamo <= 0)
{
pSoldier->snowCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
if ( camoWoreOff )
{
// Reload palettes....
if ( pSoldier->bInSector )
{
pSoldier->CreateSoldierPalettes( );
}
if ( pSoldier->bCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_JUNGLE_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->urbanCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_URBAN_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->snowCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_SNOW_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->desertCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_DESERT_WORN_OFF], pSoldier->name );
}
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
camoWoreOff = FALSE;
}
// if the merc has non-zero monster smell, degrade it by 1
if ( pSoldier->aiData.bMonsterSmell > 0 )
{
pSoldier->aiData.bMonsterSmell--;
/*
if (pSoldier->aiData.bMonsterSmell == 0)
{
// Reload palettes....
if ( pSoldier->bInSector )
{
pSoldier->CreateSoldierPalettes( );
}
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
}
*/
}
}
}
}
#ifdef JA2UB
void HandleAddingAnyAimAwayEmailsWhenLaptopGoesOnline()
{
UINT32 cnt;
INT32 iOffset;
MERCPROFILESTRUCT *pProfile;
//Loop through all the profiles
for( cnt = 0; cnt < NUM_PROFILES; cnt++)
{
pProfile = &(gMercProfiles[ cnt ]);
if (pProfile->uiDayBecomesAvailable == 0)
{
//if the merc CAN become ready
if( pProfile->bMercStatus != MERC_FIRED_AS_A_POW )
{
// 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;
UINT8 pMerc = 0;
UINT8 iMerc = 0;
UINT8 oMerc = 0;
if ( ReadXMLEmail == TRUE )
{
oMerc = cnt;
iMerc = oMerc * 1;
if ( oMerc != 0 )
pMerc = oMerc + 1;
else
pMerc = 0;
if ( gProfilesAIM[cnt].ProfilId == cnt )
AddEmailTypeXML( pMerc, iMerc, iMerc, GetWorldTotalMin(), -1 , TYPE_EMAIL_AIM_AVAILABLE);
}
else
{
// 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(),-1 ,-1, TYPE_EMAIL_EMAIL_EDT_NAME_MERC);
}
}
}
}
}
}
#endif