- Feature improvement: enemy soldiers can now free captured comrades

- Fix: when jumping through windows, AI soldiers no longer need to end their turn to avoid a deadlock

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6248 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2013-07-26 21:50:08 +00:00
parent 4e3e07ed55
commit cfe8ea5ea5
16 changed files with 163 additions and 10 deletions
+35 -2
View File
@@ -9039,9 +9039,10 @@ void SOLDIERTYPE::BeginSoldierClimbWindow( void )
this->usPendingAnimation = JUMPWINDOWS;
}
// Flugente: should be fixed now, re-enable if not
// Flugente: if an AI guy, end turn (weird endless clock syndrome)
if ( this->bTeam != OUR_TEAM )
EndAIGuysTurn( this);
//if ( this->bTeam != OUR_TEAM )
//EndAIGuysTurn( this);
// Flugente: if we are jumping through an intact window, smash it during our animation
if ( gGameExternalOptions.fCanJumpThroughClosedWindows )
@@ -15550,6 +15551,38 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength()
return value;
}
// used for an enemy liberating fellow prisoners
BOOLEAN SOLDIERTYPE::FreePrisoner()
{
// we can only free people we are facing
INT32 nextGridNoinSight = NewGridNo( this->sGridNo, DirectionInc( this->ubDirection ) );
UINT8 target = WhoIsThere2( nextGridNoinSight, this->pathing.bLevel );
// is there somebody?
if ( target != NOBODY )
{
SOLDIERTYPE* pSoldier = MercPtrs[target];
// if he is captured, free him!
// note that this would also work for prisoner civs that we spawn in our prisons. All needed would be commanding the AI to get there
if ( pSoldier->bSoldierFlagMask & (SOLDIER_POW|SOLDIER_POW_PRISON) )
{
pSoldier->bSoldierFlagMask &= ~(SOLDIER_POW|SOLDIER_POW_PRISON);
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[STR_PRISONER_X_FREES_Y], this->GetName(), pSoldier->GetName() );
// alert both soldiers
this->aiData.bAlertStatus = min(this->aiData.bAlertStatus, STATUS_RED);
pSoldier->aiData.bAlertStatus = min(pSoldier->aiData.bAlertStatus, STATUS_RED);
return TRUE;
}
}
return FALSE;
}
// Flugente: scuba gear
BOOLEAN SOLDIERTYPE::UsesScubaGear()
{
+1
View File
@@ -1539,6 +1539,7 @@ public:
// Flugente: prisoner system
BOOLEAN CanProcessPrisoners();
UINT32 GetSurrenderStrength();
BOOLEAN FreePrisoner(); // used for an enemy liberating fellow prisoners
// Flugente: scuba gear
BOOLEAN UsesScubaGear();
+8
View File
@@ -2271,9 +2271,17 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
case AI_ACTION_JUMP_WINDOW:
{
pSoldier->BeginSoldierClimbWindow();
ActionDone( pSoldier );
}
break;
case AI_ACTION_FREE_PRISONER:
{
pSoldier->FreePrisoner();
ActionDone( pSoldier );
}
break;
default:
#ifdef BETAVERSION
NumMessage("ExecuteAction - Illegal action type = ",pSoldier->aiData.bAction);
+4
View File
@@ -585,6 +585,10 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
break;
case AI_ACTION_FREE_PRISONER:
bMinPointsNeeded = APBPConstants[AP_HANDCUFF];
break;
default:
#ifdef BETAVERSION
//NumMessage("AffordableAction - Illegal action type = ",pSoldier->aiData.bAction);
+103 -7
View File
@@ -914,13 +914,20 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
}
}
////////////////////////////////////////////////////////////////////////////
// IF YOU SEE CAPTURED FRIENDS, FREE THEM!
////////////////////////////////////////////////////////////////////////////
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM && !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 10, ENEMY_TEAM, SOLDIER_POW );
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW );
if ( ubPerson != NOBODY )
{
// raise alarm!
return( AI_ACTION_RED_ALERT );
}
}
}
//ddd}
@@ -1514,13 +1521,56 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier)
return(AI_ACTION_NONE);
}
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
if( gGameExternalOptions.bNewTacticalAIBehavior )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 10, ENEMY_TEAM, SOLDIER_POW );
////////////////////////////////////////////////////////////////////////////
// IF YOU SEE CAPTURED FRIENDS, FREE THEM!
////////////////////////////////////////////////////////////////////////////
if ( ubPerson != NOBODY )
return( AI_ACTION_RED_ALERT );
// Flugente: if we see one of our buddies in handcuffs, its a clear sign of enemy activity!
// Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW );
if ( ubPerson != NOBODY )
{
// if we are close, we can release this guy
// possible only if not handcuffed (binders can be opened, handcuffs not)
if ( !HasItemFlag( (&(MercPtrs[ubPerson]->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
{
pSoldier->aiData.usActionData = ubDesiredMercDir;
return( AI_ACTION_CHANGE_FACING );
}
return(AI_ACTION_FREE_PRISONER);
}
else
{
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
return(AI_ACTION_SEEK_FRIEND);
}
}
}
else if ( !gTacticalStatus.Team[pSoldier->bTeam].bAwareOfOpposition )
{
// raise alarm!
return( AI_ACTION_RED_ALERT );
}
}
}
}
////////////////////////////////////////////////////////////////////////////
@@ -2724,6 +2774,52 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
}
*/
if( gGameExternalOptions.bNewTacticalAIBehavior )
{
////////////////////////////////////////////////////////////////////////////
// IF YOU SEE CAPTURED FRIENDS, FREE THEM!
////////////////////////////////////////////////////////////////////////////
// Flugente: if we see one of our buddies captured, it is a clear sign of enemy activity!
if ( gGameExternalOptions.fAllowPrisonerSystem && pSoldier->bTeam == ENEMY_TEAM )
{
UINT8 ubPerson = GetClosestFlaggedSoldierID( pSoldier, 20, ENEMY_TEAM, SOLDIER_POW );
if ( ubPerson != NOBODY )
{
// if we are close, we can release this guy
// possible only if not handcuffed (binders can be opened, handcuffs not)
if ( !HasItemFlag( (&(MercPtrs[ubPerson]->inv[HANDPOS]))->usItem, HANDCUFFS ) )
{
if ( PythSpacesAway(pSoldier->sGridNo, MercPtrs[ubPerson]->sGridNo) < 2 )
{
// see if we are facing this person
UINT8 ubDesiredMercDir = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(MercPtrs[ubPerson]->sGridNo),CenterY(MercPtrs[ubPerson]->sGridNo));
// if not already facing in that direction,
if ( pSoldier->ubDirection != ubDesiredMercDir )
{
pSoldier->aiData.usActionData = ubDesiredMercDir;
return( AI_ACTION_CHANGE_FACING );
}
return(AI_ACTION_FREE_PRISONER);
}
else
{
pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, MercPtrs[ubPerson]->sGridNo, 20, AI_ACTION_SEEK_FRIEND, 0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
return(AI_ACTION_SEEK_FRIEND);
}
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////
// WHEN IN THE LIGHT, GET OUT OF THERE!
////////////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -101,7 +101,8 @@ typedef enum
AI_ACTION_RELOAD_GUN,
AI_ACTION_JUMP_WINDOW, // added by Flugente: jump through a window
AI_ACTION_JUMP_WINDOW, // added by Flugente: jump through a window
AI_ACTION_FREE_PRISONER, // added by Flugente: free a prisoner
} ActionType;
+1
View File
@@ -750,6 +750,7 @@ enum
STR_PRISONER_REFUSE_SURRENDER,
STR_PRISONER_REFUSE_TAKE_PRISONERS,
SRT_PRISONER_INI_SETTING_OFF,
STR_PRISONER_X_FREES_Y,
TEXT_NUM_PRISONER_STR
};
+1
View File
@@ -7568,6 +7568,7 @@ STR16 szPrisonerTextStr[]=
L"这敌人丫宁死不从!",//L"The enemy refuses to surrender!",
L"敌人不肯拿你当囚犯 - 他们宁愿你死!", //L"The enemy refuses to take you as prisoners - they prefer you dead!",
L"这些可以在 INI 设置关闭。", // L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]=
+1
View File
@@ -7567,6 +7567,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!", // TODO.Translate
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate
+1
View File
@@ -7554,6 +7554,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!",
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]=
+1
View File
@@ -7551,6 +7551,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!", // TODO.Translate
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate
+1
View File
@@ -7377,6 +7377,7 @@ STR16 szPrisonerTextStr[]=
L"Der Gegner weigert sich aufzugeben!",
L"Der Feind weigert sich, Sie als Gefangenen zu nehmen - Er möchte Sie tod sehen!",
L"Dieses Verhalten ist ausgeschaltet in der ja2_options.ini Datei.",
L"%s hat %s befreit!",
};
STR16 szMTATextStr[]=
+1
View File
@@ -7553,6 +7553,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!", // TODO.Translate
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate
+1
View File
@@ -7573,6 +7573,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!", // TODO.Translate
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate
+1
View File
@@ -7553,6 +7553,7 @@ STR16 szPrisonerTextStr[]= // TODO.Translate
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!",
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate
+1
View File
@@ -7571,6 +7571,7 @@ STR16 szPrisonerTextStr[]=
L"The enemy refuses to surrender!",
L"The enemy refuses to take you as prisoners - they prefer you dead!", // TODO.Translate
L"This behaviour is set OFF in your ini settings.",
L"%s has freed %s!",
};
STR16 szMTATextStr[]= // TODO.Translate