mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Morale changes for AI soldiers:
- GetMoraleModifier: use bMorale for both player and AI. - CalcSuppressionTolerance: use morale as a base for tolerance for AI soldiers. - HandleSuppressionFire: morale loss for AI soldiers. - EVENT_BeginMercTurn: increase morale for AI soldiers. - TacticalCreateSoldier: Set morale = 60 + 2 * bExpLevel + Random(20) when creating AI soldier. NEW_SUPPRESSION_CODE: UseGun, UseGunNCTH: reduce shock when firing gun. AI_NEW_MORALE: limit AI morale depending on morale and shock level. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9181 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+14
-2
@@ -170,7 +170,19 @@ INT8 GetMoraleModifier( SOLDIERTYPE * pSoldier )
|
||||
{
|
||||
INT8 morale = 0;
|
||||
|
||||
if (pSoldier->flags.uiStatusFlags & SOLDIER_PC)
|
||||
// sevenfm: use bMorale for both player and AI
|
||||
if (pSoldier->aiData.bMorale > 50)
|
||||
{
|
||||
// give +1 at 55, +3 at 65, up to +5 at 95 and above
|
||||
morale = (pSoldier->aiData.bMorale - 45) / 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// give penalties down to -20 at 0 (-2 at 45, -4 by 40...)
|
||||
morale = (pSoldier->aiData.bMorale - 50) * 2 / 5;
|
||||
}
|
||||
|
||||
/*if (pSoldier->flags.uiStatusFlags & SOLDIER_PC)
|
||||
{
|
||||
if (pSoldier->aiData.bMorale > 50)
|
||||
{
|
||||
@@ -199,7 +211,7 @@ INT8 GetMoraleModifier( SOLDIERTYPE * pSoldier )
|
||||
default:
|
||||
morale = 0;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Flugente: morale modifiers
|
||||
morale = max( morale, morale * pSoldier->GetMoraleModifier( ) );
|
||||
|
||||
+13
-28
@@ -8755,13 +8755,8 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier )
|
||||
INT8 bToleranceSkill;
|
||||
UINT8 ubMaxShock = gGameExternalOptions.ubMaxSuppressionShock;
|
||||
|
||||
if (pSoldier->flags.uiStatusFlags & SOLDIER_PC)
|
||||
bToleranceMorale = pSoldier->aiData.bMorale;
|
||||
else
|
||||
bToleranceMorale = (20 + 80 * pSoldier->stats.bLife / max(OKLIFE, pSoldier->stats.bLifeMax) - 40 * min(ubMaxShock, pSoldier->aiData.bShock) / max(1, ubMaxShock));
|
||||
|
||||
// limit base tolerance to 75% when having max morale and experience level
|
||||
bToleranceSkill = (bToleranceMorale + 20 * pSoldier->stats.bExpLevel) / 4;
|
||||
bToleranceSkill = (pSoldier->aiData.bMorale + 20 * pSoldier->stats.bExpLevel) / 4;
|
||||
// calculate tolerance as percent of max tolerance from INI
|
||||
bTolerance = gGameExternalOptions.ubSuppressionToleranceMax * bToleranceSkill / 100;
|
||||
}
|
||||
@@ -9020,27 +9015,6 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
|
||||
else
|
||||
sFinalSuppressionEffectiveness = sFinalShooterDependentEffectiveness * gGameExternalOptions.usSuppressionEffectivenessAI / 100;
|
||||
|
||||
// INI-Controlled intensity. SuppressionEffectiveness acts as a percentage applied to the number of lost APs.
|
||||
// To turn off the entire Suppression system, simply set the INI value to 0. (0% AP Loss)
|
||||
// The default is obviously 100%. You can increase or decrease it, at will.
|
||||
// PLEASE NOTE that AP loss governs ALL OTHER SUPPRESSION EFFECTS.
|
||||
// sevenfm: commented out duplicated code: we don't want to apply ubFinalSuppressionEffectivness twice
|
||||
// ubPointsLost = ( ubPointsLost * sFinalSuppressionEffectiveness ) / 100;
|
||||
|
||||
// This is an upper cap for the number of APs we can lose per attack.
|
||||
// sevenfm: commented out duplicated code:
|
||||
/*
|
||||
if (usLimitSuppressionAPsLostPerAttack > 0)
|
||||
{
|
||||
if (ubPointsLost > usLimitSuppressionAPsLostPerAttack)
|
||||
{
|
||||
// Flugente: eh.. wouldn't this _always_ be 255? I suspect this should be __min
|
||||
//ubPointsLost = __max(255,(UINT8)usLimitSuppressionAPsLostPerAttack);
|
||||
ubPointsLost = __min(255,(UINT8)usLimitSuppressionAPsLostPerAttack);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// INI-Controlled intensity. SuppressionEffectiveness acts as a percentage applied to the number of lost APs.
|
||||
// To turn off the entire Suppression system, simply set the INI value to 0. (0% AP Loss)
|
||||
// The default is obviously 100%. You can increase or decrease it, at will.
|
||||
@@ -9134,7 +9108,18 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker )
|
||||
{
|
||||
for ( ubLoop2 = 0; ubLoop2 < (sPointsLost / APBPConstants[AP_LOST_PER_MORALE_DROP]); ubLoop2++ )
|
||||
{
|
||||
HandleMoraleEvent( pSoldier, MORALE_SUPPRESSED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
|
||||
// sevenfm: morale loss for AI soldiers
|
||||
if (pSoldier->ubProfile == NO_PROFILE)
|
||||
{
|
||||
if (IS_MERC_BODY_TYPE(pSoldier))
|
||||
{
|
||||
pSoldier->aiData.bMorale = max(20 + 2 * pSoldier->stats.bExpLevel, pSoldier->aiData.bMorale - 4);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleMoraleEvent(pSoldier, MORALE_SUPPRESSED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ);
|
||||
}
|
||||
// sevenfm: update ubLastMorale
|
||||
pSoldier->ubLastMorale++;
|
||||
}
|
||||
|
||||
@@ -7967,6 +7967,18 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
|
||||
// reduce the effects of any residual shock from past injuries by half
|
||||
this->aiData.bShock /= 2;
|
||||
|
||||
// sevenfm: increase morale for AI soldiers
|
||||
if (this->ubProfile == NO_PROFILE &&
|
||||
!(this->flags.uiStatusFlags & SOLDIER_VEHICLE) &&
|
||||
!AM_A_ROBOT(this) &&
|
||||
!ARMED_VEHICLE(this) &&
|
||||
this->aiData.bShock == 0 &&
|
||||
!this->aiData.bUnderFire &&
|
||||
this->aiData.bMorale < 80 + 2 * this->stats.bExpLevel)
|
||||
{
|
||||
this->aiData.bMorale = __min(80 + 2 * this->stats.bExpLevel, this->aiData.bMorale + 2 + this->stats.bExpLevel / 5);
|
||||
}
|
||||
|
||||
// if this person has heard a noise that hasn't been investigated
|
||||
if ( this->aiData.sNoiseGridno != NOWHERE )
|
||||
{
|
||||
|
||||
@@ -966,6 +966,12 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *
|
||||
Soldier.uiAnimSubFlags |= SUB_ANIM_BIGGUYTHREATENSTANCE;
|
||||
}
|
||||
|
||||
// sevenfm: max morale for AI soldiers
|
||||
if (Soldier.ubProfile == NO_PROFILE)
|
||||
{
|
||||
Soldier.aiData.bMorale = 60 + 2 * Soldier.stats.bExpLevel + Random(20);
|
||||
}
|
||||
|
||||
//For inventory, look for any face class items that may be located in the big pockets and if found, move
|
||||
//that item to a face slot and clear the pocket!
|
||||
if( Soldier.bTeam != OUR_TEAM )
|
||||
|
||||
@@ -2460,6 +2460,30 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
|
||||
OBJECTTYPE* pObjAttHand = pSoldier->GetUsedWeapon( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
|
||||
UINT16 usUBItem = pSoldier->GetUsedWeaponNumber( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
|
||||
|
||||
// sevenfm: reduce shock when firing gun, for autofire shots - apply once
|
||||
SOLDIERTYPE* pTarget = SimpleFindSoldier(sTargetGridNo, pSoldier->bTargetLevel);
|
||||
if (gGameExternalOptions.fNewSuppressionCode &&
|
||||
Item[usUBItem].usItemClass == IC_GUN &&
|
||||
pTarget &&
|
||||
(pSoldier->bDoBurst == 1 || pSoldier->bDoBurst == 0))
|
||||
{
|
||||
UINT16 noisefactor = GetPercentNoiseVolume(pObjHand);
|
||||
UINT8 ubDamage = Weapon[usUBItem].ubImpact;
|
||||
|
||||
INT8 bShotsToFire = 1;
|
||||
if (pSoldier->bDoBurst)
|
||||
{
|
||||
bShotsToFire = pSoldier->bDoAutofire ? pSoldier->bDoAutofire : GetShotsPerBurst(pObjHand);
|
||||
}
|
||||
// calculate shock reduction value 0-50%
|
||||
UINT8 ubShockReductPercent = (50 - 400 / (bShotsToFire + 8)) * noisefactor * Weapon[usUBItem].ubAttackVolume / (50 * 100);
|
||||
if (pSoldier->IsValidSecondHandShot())
|
||||
ubShockReductPercent = ubShockReductPercent * 3 / 2;
|
||||
ubShockReductPercent = __min(50, ubShockReductPercent);
|
||||
|
||||
pSoldier->aiData.bShock -= pSoldier->aiData.bShock * ubShockReductPercent / 100;
|
||||
}
|
||||
|
||||
// CALC MUZZLE SWAY
|
||||
if ( Item[ usUBItem ].usItemClass == IC_THROWING_KNIFE )
|
||||
{
|
||||
@@ -3201,6 +3225,30 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
|
||||
|
||||
usItemNum = pSoldier->usAttackingWeapon;
|
||||
|
||||
// sevenfm: reduce shock when firing gun, for autofire shots - apply once
|
||||
SOLDIERTYPE* pTarget = SimpleFindSoldier(sTargetGridNo, pSoldier->bTargetLevel);
|
||||
if (gGameExternalOptions.fNewSuppressionCode &&
|
||||
Item[usUBItem].usItemClass == IC_GUN &&
|
||||
pTarget &&
|
||||
(pSoldier->bDoBurst == 1 || pSoldier->bDoBurst == 0))
|
||||
{
|
||||
UINT16 noisefactor = GetPercentNoiseVolume(pObjUsed);
|
||||
UINT8 ubDamage = Weapon[usUBItem].ubImpact;
|
||||
|
||||
INT8 bShotsToFire = 1;
|
||||
if (pSoldier->bDoBurst)
|
||||
{
|
||||
bShotsToFire = pSoldier->bDoAutofire ? pSoldier->bDoAutofire : GetShotsPerBurst(pObjUsed);
|
||||
}
|
||||
// calculate shock reduction value 0-50%
|
||||
UINT8 ubShockReductPercent = (50 - 400 / (bShotsToFire + 8)) * noisefactor * Weapon[usUBItem].ubAttackVolume / (50 * 100);
|
||||
if (pSoldier->IsValidSecondHandShot())
|
||||
ubShockReductPercent = ubShockReductPercent * 3 / 2;
|
||||
ubShockReductPercent = __min(50, ubShockReductPercent);
|
||||
|
||||
pSoldier->aiData.bShock -= pSoldier->aiData.bShock * ubShockReductPercent / 100;
|
||||
}
|
||||
|
||||
// DEDUCT APs
|
||||
if (pSoldier->bDoBurst)
|
||||
{
|
||||
|
||||
@@ -3925,10 +3925,13 @@ INT8 CalcMoraleNew(SOLDIERTYPE *pSoldier)
|
||||
}
|
||||
|
||||
// limit AI morale when soldier is under heavy fire
|
||||
if (pSoldier->ShockLevelPercent() > 75)
|
||||
/*if (pSoldier->ShockLevelPercent() > 75)
|
||||
bMoraleCategory = min(bMoraleCategory, MORALE_NORMAL);
|
||||
else if (pSoldier->ShockLevelPercent() > 50)
|
||||
bMoraleCategory = min(bMoraleCategory, MORALE_CONFIDENT);
|
||||
bMoraleCategory = min(bMoraleCategory, MORALE_CONFIDENT);*/
|
||||
|
||||
// limit AI morale depending on morale and shock level
|
||||
bMoraleCategory = min(bMoraleCategory, max(MORALE_WORRIED, ((pSoldier->aiData.bOrders == SEEKENEMY ? pSoldier->aiData.bMorale + 20 : pSoldier->aiData.bMorale) * 100 / (100 + pSoldier->ShockLevelPercent())) / 20));
|
||||
|
||||
// prevent hopeless morale when not under attack
|
||||
if (bMoraleCategory == MORALE_HOPELESS && !pSoldier->aiData.bUnderFire)
|
||||
|
||||
Reference in New Issue
Block a user