************************************************************

* Merged Source Code from Development Trunk: Revision 4063 *
************************************************************
- Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- This will be the Source for the Beta 2011 Test

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2011-01-18 09:11:09 +00:00
parent 44e1646410
commit 91087ca8c0
469 changed files with 118108 additions and 24678 deletions
+327 -94
View File
@@ -114,9 +114,12 @@
#include "Lua Interpreter.h"
#include "bullets.h"
#endif
#include "test_space.h"
#include "connect.h"
#include "Luaglobal.h"
#include "LuaInitNPCs.h"
#include "Interface.h"
// OJW - 20090419
UINT8 giMAXIMUM_NUMBER_OF_PLAYER_MERCS = CODE_MAXIMUM_NUMBER_OF_PLAYER_MERCS;
UINT8 giMAXIMUM_NUMBER_OF_PLAYER_VEHICLES = CODE_MAXIMUM_NUMBER_OF_PLAYER_VEHICLES;
@@ -779,6 +782,7 @@ BOOLEAN InitOverhead( )
gTacticalStatus.fDidGameJustStart = TRUE;
gTacticalStatus.ubLastRequesterTargetID = NO_PROFILE;
gTacticalStatus.ubLastRequesterSurgeryTargetID = NOBODY; // SANDRO - reset surgery requester too
for ( cnt = 0; cnt < NUM_PANIC_TRIGGERS; cnt++ )
{
@@ -1426,7 +1430,7 @@ BOOLEAN ExecuteOverhead( )
}
else
{
CalcInteractiveObjectAPs( sGridNo, pStructure, &sAPCost, &sBPCost );
CalcInteractiveObjectAPs( pSoldier, sGridNo, pStructure, &sAPCost, &sBPCost ); // SANDRO - added argument
if ( EnoughPoints( pSoldier, sAPCost, sBPCost , TRUE ) )
{
@@ -1702,19 +1706,6 @@ BOOLEAN ExecuteOverhead( )
}
}
}
//if(is_client)//hayden
//{
// if(pSoldier->flags.fIsSoldierDelayed==TRUE)
// {
// continue;//in position but waiting on other clients
// }
// else
// {
// //ovh_advance=false;
// pSoldier->flags.fIsSoldierDelayed=TRUE;
// request_ovh(pSoldier->ubID);
// }
//}
}
if ( ( pSoldier->flags.uiStatusFlags & SOLDIER_PAUSEANIMOVE ) )
@@ -1969,7 +1960,8 @@ void HandleLocateToGuyAsHeWalks( SOLDIERTYPE *pSoldier )
}
}
#pragma optimize("gpt",on)
__forceinline
BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLEAN fInitialMove, UINT16 usAnimState )
{
INT16 sAPCost;
@@ -2028,15 +2020,16 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
// Do we have APs?
// CHRISL: Added penalty for jumping a fence while wearing a backpack
// Do we have APs?
// SANDRO - changed the static values to precise calculation here
if((UsingNewInventorySystem() == true) && pSoldier->inv[BPACKPOCKPOS].exists() == true)
{
sAPCost = APBPConstants[AP_JUMPFENCEBPACK];
sBPCost = APBPConstants[BP_JUMPFENCEBPACK];
sAPCost = GetAPsToJumpFence( pSoldier, TRUE );
sBPCost = GetBPsToJumpFence( pSoldier, TRUE );
}
else
{
sAPCost = APBPConstants[AP_JUMPFENCE];
sBPCost = APBPConstants[BP_JUMPFENCE];
sAPCost = GetAPsToJumpFence( pSoldier, FALSE );
sBPCost = GetBPsToJumpFence( pSoldier, FALSE );
}
@@ -2199,8 +2192,14 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
// we reuse the boobytrap gridno variable here
gsBoobyTrapGridNo = sMineGridNo;
gpBoobyTrapSoldier = pSoldier;
SetStopTimeQuoteCallback( MineSpottedDialogueCallBack );
TacticalCharacterDialogue( pSoldier, QUOTE_SUSPICIOUS_GROUND );
// silversurfer: if TRUE the merc won't comment that he found a mine, otherwise old behaviour
if (gGameExternalOptions.fMineSpottedNoTalk )
MineSpottedDialogueCallBack ();
else
{
SetStopTimeQuoteCallback( MineSpottedDialogueCallBack );
TacticalCharacterDialogue( pSoldier, QUOTE_SUSPICIOUS_GROUND );
}
}
}
else
@@ -2418,7 +2417,7 @@ BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLE
else
// ATE; First check for profile
// Forgetful guy might forget his path
if ( (pSoldier->bTeam == gbPlayerNum) && ( pSoldier->ubProfile != NO_PROFILE ) && gMercProfiles[pSoldier->ubProfile].bPersonalityTrait == FORGETFUL )
if ( (pSoldier->bTeam == gbPlayerNum) && ( pSoldier->ubProfile != NO_PROFILE ) && gMercProfiles[pSoldier->ubProfile].bDisability == FORGETFUL )
{
if ( pSoldier->ubNumTilesMovesSinceLastForget < 255 )
{
@@ -2616,7 +2615,16 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
INT32 sMineGridNo;
UINT8 ubVolume;
//uses Lua
PROFILLUA_sSectorX = pSoldier->sSectorX;
PROFILLUA_sSectorY = pSoldier->sSectorY;
PROFILLUA_bSectorZ = pSoldier->bSectorZ;
PROFILLUA_Level = pSoldier->pathing.bLevel;
PROFILLUA_ubID = pSoldier->ubID;
PROFILLUA_sGridNo = pSoldier->sGridNo;
PROFILLUA_ubDirectiono = pSoldier->ubDirection;
PROFILLUA_bTeam = pSoldier->bTeam;
// ATE; Handle bad guys, as they fade, to cancel it if
// too long...
// ONLY if fading IN!
@@ -2810,8 +2818,14 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
// we reuse the boobytrap gridno variable here
gsBoobyTrapGridNo = sMineGridNo;
gpBoobyTrapSoldier = pSoldier;
SetStopTimeQuoteCallback( MineSpottedDialogueCallBack );
TacticalCharacterDialogue( pSoldier, QUOTE_SUSPICIOUS_GROUND );
// silversurfer: if TRUE the merc won't comment that he found a mine, otherwise old behaviour
if (gGameExternalOptions.fMineSpottedNoTalk )
MineSpottedDialogueCallBack ();
else
{
SetStopTimeQuoteCallback( MineSpottedDialogueCallBack );
TacticalCharacterDialogue( pSoldier, QUOTE_SUSPICIOUS_GROUND );
}
}
}
else
@@ -2833,6 +2847,13 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
HandleSystemNewAISituation( pSoldier, FALSE );
#ifdef LUA_OVERHEAD
LetLuaMyCustomHandleAtNewGridNo(NULL,pSoldier->ubProfile, 0);
#else
//----------------Lua------------------------
if ( pSoldier->bTeam == gbPlayerNum )
{
if ( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__EPC)
@@ -2927,6 +2948,9 @@ BOOLEAN HandleAtNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving )
break;
}
}
#endif
return( TRUE );
}
@@ -3095,7 +3119,7 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF
// possibly say personality quote
if ( (pSoldier->bTeam == gbPlayerNum) && (pSoldier->ubProfile != NO_PROFILE && pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__PLAYER_CHARACTER) && !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) )
{
switch ( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait )
switch ( gMercProfiles[ pSoldier->ubProfile ].bDisability )
{
case PSYCHO:
if ( Random( 50 ) == 0 )
@@ -3540,7 +3564,22 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
// check to see if dynamo quest is on
if ( gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS)
{
EndQuest( QUEST_FREE_DYNAMO, pSoldierOld->sSectorX, pSoldierOld->sSectorY );
// SANDRO - quest failed if Dynamo is killed
InternalEndQuest( QUEST_FREE_DYNAMO, pSoldierOld->sSectorX, pSoldierOld->sSectorY, FALSE );
}
break;
// SANDRO - if we kill Carmen with Slay in our team, end the terrorists quest
case CARMEN :
// Carmen must have seen Slay, to finish the quest properly, he must know we betrayd him
if ( pSoldierOld->aiData.bAttitude == ATTACKSLAYONLY )
{
pOther = FindSoldierByProfileID( SLAY, FALSE );
if (pOther && pOther->stats.bLife && pOther->bTeam == gbPlayerNum &&
pSoldierOld->sSectorX == pOther->sSectorX && pSoldierOld->sSectorY == pOther->sSectorY)
{
// Slay is in sector and alive, Carmen dead, end quest, award some exp
EndQuest( QUEST_KILL_TERRORISTS, pSoldierOld->sSectorX, pSoldierOld->sSectorY );
}
}
break;
case KINGPIN:
@@ -3569,6 +3608,11 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
HandleNPCDoAction( DOREEN, NPC_ACTION_FREE_KIDS, 0 );
}
break;
// SANDRO - Check if queen bitch is dead
case QUEEN:
// Muhahahahaaa, QUEST COMPLETED! Give us everything!! Exp, glory, fame!
EndQuest( QUEST_KILL_DEIDRANNA, pSoldierOld->sSectorX, pSoldierOld->sSectorY );
break;
}
// Are we looking at the queen?
@@ -3608,7 +3652,8 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
}
// If the militia's killer is known
if ( pSoldierOld->ubAttackerID != NOBODY )
// silversurfer: did the player team kill the militia? If not, militia shouldn't become hostile towards the player.
if ( pSoldierOld->ubAttackerID != NOBODY && MercPtrs[ pSoldierOld->ubAttackerID ]->bTeam == OUR_TEAM )
{
// also treat this as murder - but player will never be blamed for militia death he didn't cause
// HEADROCK HAM 3.6: Actually this function never runs for militia (see function for details)
@@ -3679,21 +3724,49 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
// killing crows/cows is not worth any experience!
if ( ( pSoldierOld->ubBodyType != CROW ) && ( pSoldierOld->ubBodyType != COW ) && pSoldierOld->ubLastDamageReason != TAKE_DAMAGE_BLOODLOSS )
if ( ( pSoldierOld->ubBodyType != CROW ) && ( pSoldierOld->ubBodyType != COW ) ) //&& pSoldierOld->ubLastDamageReason != TAKE_DAMAGE_BLOODLOSS ) // SANDRO - why not give exp for bleeding out?
{
UINT8 ubAssister;
UINT8 ubAssister = NOBODY;
// if it was a kill by a player's merc
if (pSoldierOld->ubAttackerID != NOBODY && MercPtrs[ pSoldierOld->ubAttackerID ]->bTeam == gbPlayerNum )
{
// SANDRO - for special NPCs, you gain more experiences
UINT16 usNumExpChances = ( 10 * pSoldierOld->stats.bExpLevel ); // basic value
switch( pSoldierOld->ubProfile )
{
case CARMEN:
case QUEEN:
case JOE:
case ANNIE:
case CHRIS:
case KINGPIN:
case TIFFANY:
case T_REX:
case DRUGGIST:
case GENERAL:
case JACK:
case OLAF:
case RAY:
case OLGA:
case TYRONE:
case MIKE:
usNumExpChances *= 2; // make it double for special guys
if( gGameExternalOptions.usSpecialNPCStronger > 0 ) // if set stronger, adjust the value
{
usNumExpChances += (usNumExpChances * gGameExternalOptions.usSpecialNPCStronger / 100);
}
break;
}
// EXPERIENCE CLASS GAIN: Earned a kill
StatChange( MercPtrs[ pSoldierOld->ubAttackerID ], EXPERAMT, (UINT16)( 10 * pSoldierOld->stats.bExpLevel ), FALSE );
StatChange( MercPtrs[ pSoldierOld->ubAttackerID ], EXPERAMT, usNumExpChances, FALSE );
}
// JA2 Gold: if previous and current attackers are the same, the next-to-previous attacker gets the assist
if (pSoldierOld->ubPreviousAttackerID == pSoldierOld->ubAttackerID)
{
ubAssister = pSoldierOld->ubNextToPreviousAttackerID;
if (pSoldierOld->ubNextToPreviousAttackerID != pSoldierOld->ubAttackerID ) // SANDRO - carefully with this, if we are still one person don't do this
ubAssister = pSoldierOld->ubNextToPreviousAttackerID;
}
else
{
@@ -3744,6 +3817,7 @@ UINT8 LastActiveTeamMember( UINT8 ubTeam )
void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier )
{
UINT16 iCounter2;
// Check if we are a threat!
if ( !pSoldier->aiData.bNeutral && (pSoldier->bSide != gbPlayerNum ) )
{
@@ -3751,7 +3825,7 @@ void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier )
// We need to exclude cases where a kid is not neutral anymore, but is defenceless!
if ( pSoldier->bTeam == CIV_TEAM )
{
// maybe increment num enemy attacked
/* // maybe increment num enemy attacked
switch ( pSoldier->ubCivilianGroup )
{
case REBEL_CIV_GROUP:
@@ -3766,6 +3840,33 @@ void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier )
// nope!
break;
}
//New Group by Jazz
for( iCounter2 = UNNAMED_CIV_GROUP_15; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
{
if (pSoldier->ubCivilianGroup == iCounter2)
{
if ( FindObjClass( pSoldier, IC_WEAPON ) != NO_SLOT )
{
gTacticalStatus.bNumFoughtInBattle[ pSoldier->bTeam ]++;
}
}
}
*/
//New Group by Jazz
for( iCounter2 = REBEL_CIV_GROUP; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
{
if ( pSoldier->ubCivilianGroup == iCounter2 && zCivGroupName[iCounter2].AddToBattle == TRUE )
{
if ( FindObjClass( pSoldier, IC_WEAPON ) != NO_SLOT )
{
gTacticalStatus.bNumFoughtInBattle[ pSoldier->bTeam ]++;
}
}
}
}
else
{
@@ -5437,14 +5538,17 @@ void HandleTeamServices( UINT8 ubTeamNum )
if ( pTargetSoldier->ubServiceCount )
{
BOOLEAN fThrowMessage = (pTargetSoldier->bBleeding ? TRUE : FALSE); // added by SANDRO
usKitPts = TotalPoints( &(pTeamSoldier->inv[ HANDPOS ] ) );
uiPointsUsed = pTeamSoldier->SoldierDressWound( pTargetSoldier, usKitPts, usKitPts );
// Determine if they are all banagded
if ( !pTargetSoldier->bBleeding && pTargetSoldier->stats.bLife >= OKLIFE )
if ( !pTargetSoldier->bBleeding && pTargetSoldier->stats.bLife >= OKLIFE && !(pTargetSoldier->iHealableInjury >= 100 && pTeamSoldier->fDoingSurgery)) // check for surgery added by SANDRO
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name );
if ( fThrowMessage ) // throw message "all bandaged" only if there was something to bandage - SANDRO
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name );
// Cancel all services for this guy!
pTargetSoldier->ReceivingSoldierCancelServices( );
@@ -5523,14 +5627,17 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier )
if ( pTargetSoldier->ubServiceCount )
{
BOOLEAN fThrowMessage = (pTargetSoldier->bBleeding ? TRUE : FALSE); // added by SANDRO
usKitPts = TotalPoints( &(pTeamSoldier->inv[ HANDPOS ] ) );
uiPointsUsed = pTeamSoldier->SoldierDressWound( pTargetSoldier, usKitPts, usKitPts );
// Determine if they are all banagded
if ( !pTargetSoldier->bBleeding && pTargetSoldier->stats.bLife >= OKLIFE )
if ( !pTargetSoldier->bBleeding && pTargetSoldier->stats.bLife >= OKLIFE && !(pTargetSoldier->iHealableInjury >= 100 && pTeamSoldier->fDoingSurgery)) // check for surgery added by SANDRO
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name );
if ( fThrowMessage ) // throw message "all bandaged" only if there was something to bandage - SANDRO
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ MERC_IS_ALL_BANDAGED_STR ], pTargetSoldier->name );
// Cancel all services for this guy!
pTargetSoldier->ReceivingSoldierCancelServices( );
@@ -5552,16 +5659,24 @@ void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier )
}
else
{
bSlot = FindFirstAidKit ( pTeamSoldier);
if ( bSlot == NO_SLOT )
// SANDRO - on surgery, only search for medic bags
if (pTeamSoldier->fDoingSurgery)
{
bSlot = FindMedKit ( pTeamSoldier );
}
else
{
bSlot = FindFirstAidKit ( pTeamSoldier);
if ( bSlot == NO_SLOT )
{
bSlot = FindMedKit ( pTeamSoldier );
}
}
}
if ( bSlot != NO_SLOT )
{
SwapObjs( pTeamSoldier, HANDPOS, bSlot, TRUE );
SwapObjs( pTeamSoldier, HANDPOS, bSlot, FALSE ); // SANDRO - changed to FALSE, so we can continue in the service (???)
}
else
{
@@ -5591,7 +5706,8 @@ void CommonEnterCombatModeCode( )
//gTacticalStatus.ubAttackBusyCount = 0;
// Reset num enemies fought flag...
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
// SANDRO - removed from here
//memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
gTacticalStatus.ubLastBattleSectorX = (UINT8) gWorldSectorX;
gTacticalStatus.ubLastBattleSectorY = (UINT8) gWorldSectorY;
gTacticalStatus.fLastBattleWon = FALSE;
@@ -5626,7 +5742,8 @@ void CommonEnterCombatModeCode( )
pSoldier->flags.uiStatusFlags &= ~SOLDIER_UNDERAICONTROL;
// Check if this guy is an enemy....
CheckForPotentialAddToBattleIncrement( pSoldier );
// SANDRO - don't check this here, we've already checked that once
//CheckForPotentialAddToBattleIncrement( pSoldier );
// If guy is sleeping, wake him up!
if ( pSoldier->flags.fMercAsleep == TRUE )
@@ -5835,7 +5952,8 @@ void ExitCombatMode( )
}
// Change music modes
gfForceMusicToTense = TRUE;
// unused
//gfForceMusicToTense = TRUE;
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
@@ -6205,7 +6323,9 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen )
// Double check by seeing if we have any active enemies in sector!
if ( NumEnemyInSectorNotDeadOrDying( ) > 0 )
{
SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT );
//comm by ddd SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT );
if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
SayQuoteFromAnyBodyInSector( QUOTE_WARNING_OUTSTANDING_ENEMY_AFTER_RT );
}
}
}
@@ -6218,7 +6338,8 @@ BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen )
*/
// Begin tense music....
gfForceMusicToTense = TRUE;
// unused
//gfForceMusicToTense = TRUE;
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
return( TRUE );
@@ -6238,7 +6359,7 @@ void DeathNoMessageTimerCallback( void )
if (!isOwnTeamWipedOut)
{
ScreenMsg( FONT_LTGREEN, MSG_CHAT, MPClientMessage[40] );
if(!DISABLE_SPEC_MODE)
if(!cDisableSpectatorMode)
{
gTacticalStatus.uiFlags |= SHOW_ALL_MERCS;//hayden
ScreenMsg( FONT_YELLOW, MSG_CHAT, MPClientMessage[41] );
@@ -6367,6 +6488,8 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
// Set enemy presence to false
// This is safe 'cause we're about to unload the friggen sector anyway....
gTacticalStatus.fEnemyInSector = FALSE;
// SANDRO - reset number of enemies here
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
// If here, the battle has been lost!
UnSetUIBusy( (UINT8)gusSelectedSoldier );
@@ -6380,6 +6503,13 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
HandleMoraleEvent( NULL, MORALE_HEARD_BATTLE_LOST, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_BATTLE_LOST, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
// SANDRO - end quest if cleared the sector after interrogation (sector N7 by Meduna)
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[ QUEST_INTERROGATION ] == QUESTINPROGRESS )
{
// Quest failed
InternalEndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE );
}
// Play death music
SetMusicMode( MUSIC_TACTICAL_DEATH );
@@ -6475,7 +6605,13 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
{
if( pTeamSoldier->bTeam == gbPlayerNum )
{
gMercProfiles[pTeamSoldier->ubProfile].usBattlesFought++;
// SANDRO - records - num tactical battles
gMercProfiles[pTeamSoldier->ubProfile].records.usBattlesTactical++;
// largest battle experienced
if (gMercProfiles[pTeamSoldier->ubProfile].records.usLargestBattleFought < ( gTacticalStatus.bNumFoughtInBattle[ ENEMY_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CREATURE_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CIV_TEAM ] ))
{
gMercProfiles[pTeamSoldier->ubProfile].records.usLargestBattleFought = ( gTacticalStatus.bNumFoughtInBattle[ ENEMY_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CREATURE_TEAM ] + gTacticalStatus.bNumFoughtInBattle[ CIV_TEAM ] );
}
// If this guy is OKLIFE & not standing, make stand....
if ( pTeamSoldier->stats.bLife >= OKLIFE && !pTeamSoldier->bCollapsed )
@@ -6491,19 +6627,21 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
gfUIStanceDifferent = TRUE;
pTeamSoldier->bStealthMode = FALSE;
fInterfacePanelDirty = DIRTYLEVEL2;
if ( gAnimControl[ pTeamSoldier->usAnimState ].ubHeight != ANIM_STAND )
{
pTeamSoldier->ChangeSoldierStance( ANIM_STAND );
}
else
{
// If they are aiming, end aim!
usAnimState = PickSoldierReadyAnimation( pTeamSoldier, TRUE );
if ( usAnimState != INVALID_ANIMATION )
//DBrot: Stance change
if (gGameExternalOptions.fStandUpAfterBattle){
if ( gAnimControl[ pTeamSoldier->usAnimState ].ubHeight != ANIM_STAND )
{
pTeamSoldier->EVENT_InitNewSoldierAnim( usAnimState, 0, FALSE );
pTeamSoldier->ChangeSoldierStance( ANIM_STAND );
}
else
{
// If they are aiming, end aim!
usAnimState = PickSoldierReadyAnimation( pTeamSoldier, TRUE );
if ( usAnimState != INVALID_ANIMATION )
{
pTeamSoldier->EVENT_InitNewSoldierAnim( usAnimState, 0, FALSE );
}
}
}
}
@@ -6531,6 +6669,12 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
if (!is_networked)
ShouldBeginAutoBandage( );
}
// SANDRO - end quest if cleared the sector after interrogation (sector N7 by Meduna)
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[ QUEST_INTERROGATION ] == QUESTINPROGRESS )
{
// Complete quest
EndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
}
// Say battle end quote....
@@ -6556,6 +6700,8 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
}
}
// SANDRO - reset number of enemies here
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
}
else
{
@@ -6583,7 +6729,14 @@ BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated )
pTeamSoldier->aiData.bNewSituation = FALSE;
pTeamSoldier->aiData.bOrders = STATIONARY;
if ( pTeamSoldier->stats.bLife < OKLIFE )
{
// SANDRO - the insta-healable value for doctor trait check
pTeamSoldier->iHealableInjury -= ((OKLIFE - pTeamSoldier->stats.bLife) * 100);
if (pTeamSoldier->iHealableInjury < 0)
pTeamSoldier->iHealableInjury = 0;
pTeamSoldier->stats.bLife = OKLIFE;
}
pTeamSoldier->bBleeding = 0; // let's think, the autobandage was done for the militia too
}
@@ -7183,7 +7336,16 @@ BOOLEAN KillIncompacitatedEnemyInSector( )
if ( !pTeamSoldier->aiData.bNeutral && (pTeamSoldier->bSide != gbPlayerNum ) )
{
// KIll......
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
// SANDRO - if the soldier is bleeding out, consider this damage as done by the last attacker
if ( pTeamSoldier->ubAttackerID != NOBODY )
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubAttackerID, NOWHERE, 0, TRUE );
else if ( pTeamSoldier->ubPreviousAttackerID != NOBODY )
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubPreviousAttackerID, NOWHERE, 0, TRUE );
else if ( pTeamSoldier->ubNextToPreviousAttackerID != NOBODY )
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, pTeamSoldier->ubNextToPreviousAttackerID, NOWHERE, 0, TRUE );
else
pTeamSoldier->SoldierTakeDamage( ANIM_CROUCH, pTeamSoldier->stats.bLife, 100, TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, TRUE );
fReturnVal = TRUE;
}
}
@@ -7237,17 +7399,28 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier )
if ( pSoldier->ubProfile != NO_PROFILE )
{
// change tolerance based on attitude
switch ( gMercProfiles[ pSoldier->ubProfile ].bAttitude )
// SANDRO - check for character traits
if ( gGameOptions.fNewTraitSystem )
{
case ATT_AGGRESSIVE:
bTolerance += 2;
break;
case ATT_COWARD:
bTolerance += -2;
break;
default:
break;
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
bTolerance += -2;
else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
bTolerance += 2;
}
else
{
// change tolerance based on attitude
switch ( gMercProfiles[ pSoldier->ubProfile ].bAttitude )
{
case ATT_AGGRESSIVE:
bTolerance += 2;
break;
case ATT_COWARD:
bTolerance += -2;
break;
default:
break;
}
}
}
else
@@ -7290,6 +7463,19 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier )
}
}
// SANDRO - STOMP traits - squadleader's bonus to suppression tolerance
if ( gGameOptions.fNewTraitSystem && IS_MERC_BODY_TYPE(pSoldier) &&
(pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == MILITIA_TEAM || pSoldier->bTeam == gbPlayerNum) )
{
UINT8 ubNumberOfSL = GetSquadleadersCountInVicinity( pSoldier, FALSE, FALSE );
// Also take ourselves into account
if ((ubNumberOfSL < gSkillTraitValues.ubSLMaxBonuses) && HAS_SKILL_TRAIT( pSoldier, SQUADLEADER_NT ))
{
ubNumberOfSL = max( gSkillTraitValues.ubSLMaxBonuses, (ubNumberOfSL + NUM_SKILL_TRAITS( pSoldier, SQUADLEADER_NT )) );
}
bTolerance += (bTolerance * gSkillTraitValues.ubSLOverallSuppresionBonusPercent * ubNumberOfSL / 100);
}
bTolerance = __max(bTolerance, gGameExternalOptions.ubSuppressionToleranceMin);
bTolerance = __min(bTolerance, gGameExternalOptions.ubSuppressionToleranceMax);
@@ -7398,6 +7584,8 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
bShockLimit = MAXIMUM_SUPPRESSION_SHOCK;
// The amount of shock received depends on how many APs we've lost - Every AP lost will cause one
// point of shock. This is then divided by 4 if using the 100AP system.
if (uiShockPerAPLossDivisor == 0) // SANDRO - check if we are not going to divide by zero
uiShockPerAPLossDivisor = 4; // set to default value in this case
bShockValue = ubPointsLost / uiShockPerAPLossDivisor;
bShockValue = __max(0,bShockValue);
@@ -7432,7 +7620,26 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
fCower = false;
if ( gGameExternalOptions.usSuppressionShockEffect > 0 )
{
if (pSoldier->aiData.bShock >= bTolerance)
// SANDRO - STOMP traits
INT8 bShockForCower = pSoldier->aiData.bShock;
if ( gGameOptions.fNewTraitSystem )
{
// Squadleader's resistance to cowering
if ( HAS_SKILL_TRAIT( pSoldier, SQUADLEADER_NT ))
{
bShockForCower = (INT8)((bShockForCower * (100 - gSkillTraitValues.ubSLFearResistance * NUM_SKILL_TRAITS( pSoldier, SQUADLEADER_NT )) /100) + 0.5);
}
// Check for character traits
if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_INTELLECTUAL )
{
bShockForCower = (INT8)((bShockForCower * 23 / 20 ) + 0.5); // +15% as shock
}
else if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
{
bShockForCower = (INT8)((bShockForCower * 17 / 20 ) + 0.5); // -15% as shock
}
}
if (bShockForCower >= bTolerance)
{
fCower = true;
@@ -7467,13 +7674,13 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
// can't change stance below prone!
break;
case ANIM_CROUCH:
if (ubPointsLost >= APBPConstants[AP_PRONE] && IsValidStance( pSoldier, ANIM_PRONE ) && gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE )
if (ubPointsLost >= GetAPsProne(pSoldier, TRUE) && IsValidStance( pSoldier, ANIM_PRONE ) && gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) // SANDRO - changed to GetAPsProne
{
sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL );
// HEADROCK: Added cowering.
if (TileIsOutOfBounds(sClosestOpponent) || SpacesAway( pSoldier->sGridNo, sClosestOppLoc ) > 8 || fCower)
{
ubPointsLost -= APBPConstants[AP_PRONE];
ubPointsLost -= GetAPsProne(pSoldier, TRUE);
ubNewStance = ANIM_PRONE;
}
}
@@ -7484,7 +7691,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
// can't change stance here!
break;
}
else if (ubPointsLost >= (APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE]) && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) && IsValidStance( pSoldier, ANIM_PRONE ) )
else if (ubPointsLost >= (GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE)) && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_PRONE ) && IsValidStance( pSoldier, ANIM_PRONE ) ) // SANDRO - changed to GetAPsCrouch/Prone
{
sClosestOpponent = ClosestKnownOpponent( pSoldier, &sClosestOppLoc, NULL );
// HEADROCK: Added cowering.
@@ -7507,7 +7714,7 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
ubNewStance = ANIM_CROUCH;
}
}
else if ( ubPointsLost >= APBPConstants[AP_CROUCH] && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) && IsValidStance( pSoldier, ANIM_CROUCH ) )
else if ( ubPointsLost >= GetAPsCrouch(pSoldier, TRUE) && ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight != ANIM_CROUCH ) && IsValidStance( pSoldier, ANIM_CROUCH ) ) // SANDRO - changed to GetAPsCrouch
{
// crouch!
ubNewStance = ANIM_CROUCH;
@@ -7668,11 +7875,16 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp
}
}
if ( (pTarget->bTeam == MILITIA_TEAM) && (pTarget->bSide == gbPlayerNum) )
// silversurfer: if militia was attacked and not already hostile make them hostile towards the player
// but only IF the player was the attacker!
if ( (pTarget->bTeam == MILITIA_TEAM) && (pSoldier->bTeam == OUR_TEAM) )
{
// HEADROCK HAM 3.6: INI setting controls their response
{
if (gGameExternalOptions.ubCanMilitiaBecomeHostile == 2)
if (pTarget->flags.fIntendedTarget // Must be intentional
&& gGameExternalOptions.ubCanMilitiaBecomeHostile == 2 // INI setting
&& pTarget->bSide == gbPlayerNum // Must not be hostile by now
)
{
// rebel militia attacked by the player!
MilitiaChangesSides();
@@ -8161,7 +8373,9 @@ SOLDIERTYPE *InternalReduceAttackBusyCount( )
// Display quote!
if ( !AM_AN_EPC( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ] ) )
{
TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ], (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, gTacticalStatus.usItemsSeenOnAttackGridNo, 0 );
//ddd TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ], (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, gTacticalStatus.sItemsSeenOnAttackGridNo, 0 );
if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
TacticalCharacterDialogueWithSpecialEvent( MercPtrs[ gTacticalStatus.ubItemsSeenOnAttackSoldier ], (UINT16)( QUOTE_SPOTTED_SOMETHING_ONE + Random( 2 ) ), DIALOGUE_SPECIAL_EVENT_SIGNAL_ITEM_LOCATOR_START, gTacticalStatus.usItemsSeenOnAttackGridNo, 0 );
}
else
{
@@ -8544,7 +8758,7 @@ void EndBattleWithUnconsciousGuysCallback( UINT8 bExitValue )
else
{
ScreenMsg( FONT_LTGREEN, MSG_CHAT, MPClientMessage[40] );
if(!DISABLE_SPEC_MODE)
if(!cDisableSpectatorMode)
{
gTacticalStatus.uiFlags |= SHOW_ALL_MERCS;//hayden
ScreenMsg( FONT_YELLOW, MSG_CHAT, MPClientMessage[41] );
@@ -8916,6 +9130,7 @@ INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier )
UINT16 usEffectiveRangeToLeader = 0;
INT16 usBestLeader = 0;
INT16 usFriendBonus = 0;
UINT8 ubLevelDifference = 0;
// Run through each friendly.
for ( UINT8 iCounter = gTacticalStatus.Team[ pSoldier->bTeam ].bFirstID ; iCounter <= gTacticalStatus.Team[ pSoldier->bTeam ].bLastID ; iCounter ++ )
@@ -8924,27 +9139,39 @@ INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier )
// Make sure that character is alive, not too shocked, and conscious, and of higher experience level
// than the character being suppressed.
if (pLeader != pSoldier && pLeader->bActive && pLeader->aiData.bShock < pLeader->stats.bLeadership/5 &&
pLeader->stats.bLife >= OKLIFE && pLeader->stats.bExpLevel >= pSoldier->stats.bExpLevel)
pLeader->stats.bLife >= OKLIFE )
{
ubLevelDifference = (pLeader->stats.bExpLevel - pSoldier->stats.bExpLevel );
// Calculate character's leadership and range/3
usEffectiveLeadership = ((EffectiveLeadership( pLeader ) - 25) / 15);
usEffectiveRangeToLeader = PythSpacesAway( pSoldier->sGridNo, pLeader->sGridNo ) / 3;
// If leader is within range of his leadership stat
if (usEffectiveRangeToLeader <= usEffectiveLeadership+1)
{
// The difference in experience level is important!
usEffectiveLeadership += (pLeader->stats.bExpLevel - pSoldier->stats.bExpLevel);
// Reduce effective leadership with every 3 tiles of distance
usEffectiveLeadership -= usEffectiveRangeToLeader-1;
// If this is the best leader we've seen so far,
if (usEffectiveLeadership > usBestLeader)
// SANDRO - add effective leadership and level to determine if we can help our friend to feel better :)
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pLeader, SQUADLEADER_NT ) )
{
ubLevelDifference += (gSkillTraitValues.ubSLEffectiveLevelAsStandby * NUM_SKILL_TRAITS( pLeader, SQUADLEADER_NT ));
usEffectiveLeadership += (gSkillTraitValues.ubSLEffectiveLevelAsStandby * NUM_SKILL_TRAITS( pLeader, SQUADLEADER_NT ));
}
if ( ubLevelDifference >= 0 )
{
// If leader is within range of his leadership stat
if (usEffectiveRangeToLeader <= usEffectiveLeadership+1)
{
// Set this as the best leader
usBestLeader = usEffectiveLeadership;
// The difference in experience level is important!
usEffectiveLeadership += ubLevelDifference;
// Reduce effective leadership with every 3 tiles of distance
usEffectiveLeadership -= usEffectiveRangeToLeader-1;
// If this is the best leader we've seen so far,
if (usEffectiveLeadership > usBestLeader)
{
// Set this as the best leader
usBestLeader = usEffectiveLeadership;
}
// Friends within range always give at least one tolerance bonus point.
usFriendBonus += 1;
}
// Friends within range always give at least one tolerance bonus point.
usFriendBonus += 1;
}
}
// Incapacitated or heavily suppressed friends will not be good for our tolerance!
@@ -8959,6 +9186,12 @@ INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier )
usEffectiveLeadership = (pLeader->stats.bExpLevel - pSoldier->stats.bExpLevel) / __max(1,(usEffectiveRangeToLeader/2));
usFriendBonus -= __max(1, usEffectiveLeadership);
}
// SANDRO - however, dead squadleader is very bad for our psychics
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pLeader, SQUADLEADER_NT ) &&
( pLeader->flags.uiStatusFlags & SOLDIER_DEAD ) && usEffectiveRangeToLeader <= 10 )
{
usFriendBonus -= ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * NUM_SKILL_TRAITS( pLeader, SQUADLEADER_NT ));
}
}
}