mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
More turncoat-related fixes and tweaks (by rftr):
- added "recruit turncoat" to the talk menu - recruiting turncoats now costs AP (AP_TALK in APBPConstants) - fixed groups not decrementing soldiers when activating turncoats - fixed a hang when activating a sector with 100% turncoats in realtime git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8988 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -3338,25 +3338,28 @@ bool RemoveOneTurncoat( INT16 sSectorX, INT16 sSectorY, UINT8 aSoldierClass )
|
||||
switch ( aSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat )
|
||||
if ( pGroup->pEnemyGroup->ubNumAdmins_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumAdmins )
|
||||
{
|
||||
pGroup->pEnemyGroup->ubNumAdmins_Turncoat--;
|
||||
pGroup->pEnemyGroup->ubNumAdmins--;
|
||||
pGroup->ubGroupSize--;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat )
|
||||
if ( pGroup->pEnemyGroup->ubNumTroops_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumTroops )
|
||||
{
|
||||
pGroup->pEnemyGroup->ubNumTroops_Turncoat--;
|
||||
pGroup->pEnemyGroup->ubNumTroops--;
|
||||
pGroup->ubGroupSize--;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SOLDIER_CLASS_ELITE:
|
||||
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat )
|
||||
if ( pGroup->pEnemyGroup->ubNumElites_Turncoat && pGroup->ubGroupSize && pGroup->pEnemyGroup->ubNumElites )
|
||||
{
|
||||
pGroup->pEnemyGroup->ubNumElites_Turncoat--;
|
||||
pGroup->pEnemyGroup->ubNumElites--;
|
||||
pGroup->ubGroupSize--;
|
||||
return true;
|
||||
}
|
||||
|
||||
+47
-20
@@ -10806,6 +10806,9 @@ void TurnCoatAttemptMessageBoxCallBack( UINT8 ubExitValue )
|
||||
|
||||
AddIntel( -intelbribeneeded, TRUE );
|
||||
}
|
||||
|
||||
// spend AP
|
||||
DeductPoints( MercPtrs[gusSelectedSoldier], APBPConstants[AP_TALK], 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
//ReduceAttackBusyCount();
|
||||
}
|
||||
@@ -10864,7 +10867,7 @@ void HandleTurncoatAttempt( SOLDIERTYPE* pSoldier )
|
||||
wcscpy( gzUserDefinedButton1, szTurncoatText[8] );
|
||||
wcscpy( gzUserDefinedButton2, pEpcMenuStrings[4] );
|
||||
|
||||
DoMessageBox( MSG_BOX_BASIC_STYLE, szTurncoatText[7], guiCurrentScreen, ( MSG_BOX_FLAG_GENERIC_TWO_BUTTONS | MSG_BOX_FLAG_DROPDOWN_1 ),
|
||||
DoMessageBox( MSG_BOX_BASIC_STYLE, szTurncoatText[7], GAME_SCREEN, ( MSG_BOX_FLAG_GENERIC_TWO_BUTTONS | MSG_BOX_FLAG_DROPDOWN_1 ),
|
||||
TurnCoatAttemptMessageBoxCallBack, NULL );
|
||||
}
|
||||
}
|
||||
@@ -10877,9 +10880,11 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
|
||||
if ( ubExitValue == 1 )
|
||||
{
|
||||
DeductPoints( MercPtrs[gusSelectedSoldier], APBPConstants[AP_TALK], 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
if ( !gGameExternalOptions.fEnemyCanSurrender )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[ SRT_PRISONER_INI_SETTING_OFF ] );
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11026,20 +11031,14 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
}
|
||||
// we offered to surrender OURSELVES TO the enemy, or are attempting to turn a soldier into a turncoat
|
||||
// we offered to surrender OURSELVES TO the enemy
|
||||
else if ( ubExitValue == 2 )
|
||||
{
|
||||
// we cannot surrender to bandits, talk instead
|
||||
if ( MercPtrs[prisonerdialoguetargetID]->bTeam == CREATURE_TEAM )
|
||||
{
|
||||
// normal dialog
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
return;
|
||||
}
|
||||
DeductPoints( MercPtrs[gusSelectedSoldier], APBPConstants[AP_TALK], 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
if ( !gGameExternalOptions.fPlayerCanAsktoSurrender )
|
||||
if ( !gGameExternalOptions.fPlayerCanAsktoSurrender || MercPtrs[prisonerdialoguetargetID]->bTeam == CREATURE_TEAM )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[ SRT_PRISONER_INI_SETTING_OFF ] );
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -11086,6 +11085,8 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// we distract the enemy by essentially talking them to death
|
||||
else if ( ubExitValue == 3 )
|
||||
{
|
||||
DeductPoints( MercPtrs[gusSelectedSoldier], APBPConstants[AP_TALK], 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
// Flugente: if we are disguised and talk to a non-profile NPC, we will continue to 'chat' with the enemy as long as we aren't ordered to do something else.
|
||||
// This way we can easily order our spies to 'distract' enemies
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) &&
|
||||
@@ -11109,10 +11110,28 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal dialog
|
||||
StartCivQuote( MercPtrs[ prisonerdialoguetargetID ] );
|
||||
else
|
||||
{
|
||||
// rftr: try to recruit a turncoat
|
||||
if (gSkillTraitValues.fCOTurncoats == TRUE &&
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier ) &&
|
||||
pSoldier->bTeam == gbPlayerNum &&
|
||||
MercPtrs[prisonerdialoguetargetID] &&
|
||||
MercPtrs[prisonerdialoguetargetID]->bTeam == ENEMY_TEAM &&
|
||||
MercPtrs[prisonerdialoguetargetID]->ubProfile == NO_PROFILE &&
|
||||
MercPtrs[prisonerdialoguetargetID]->aiData.bAlertStatus < STATUS_RED &&
|
||||
!MercPtrs[prisonerdialoguetargetID]->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
{
|
||||
MSYS_RemoveRegion(&(gMsgBox.BackRegion));
|
||||
pSoldier->UseSkill(SKILLS_CREATE_TURNCOAT, MercPtrs[prisonerdialoguetargetID]->sGridNo, MercPtrs[prisonerdialoguetargetID]->ubID);
|
||||
// AP reduction is handled inside the turncoat attempt flow (TurnCoatAttemptMessageBoxCallBack)
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal dialog
|
||||
DeductPoints( MercPtrs[gusSelectedSoldier], APBPConstants[AP_TALK], 0, UNTRIGGERED_INTERRUPT );
|
||||
StartCivQuote(MercPtrs[prisonerdialoguetargetID]);
|
||||
}
|
||||
}
|
||||
|
||||
ReduceAttackBusyCount( );
|
||||
@@ -11172,10 +11191,17 @@ void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
// remember the target's ID
|
||||
prisonerdialoguetargetID = pSoldier->ubID;
|
||||
|
||||
// open a dialogue box and see wether we really want to offer this, or just talk
|
||||
wcscpy( gzUserDefinedButton[0], TacticalStr[ PRISONER_DEMAND_SURRENDER_STR ] );
|
||||
if (gGameExternalOptions.fEnemyCanSurrender && pSoldier->CanBeCaptured())
|
||||
{
|
||||
// open a dialogue box and see whether we really want to offer this, or just talk
|
||||
wcscpy(gzUserDefinedButton[0], TacticalStr[PRISONER_DEMAND_SURRENDER_STR]);
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy(gzUserDefinedButton[0], TacticalStr[PRISONER_TALK_STR]);
|
||||
}
|
||||
|
||||
if ( pSoldier->bTeam != CREATURE_TEAM )
|
||||
if (gGameExternalOptions.fPlayerCanAsktoSurrender && pSoldier->bTeam != CREATURE_TEAM)
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[ PRISONER_OFFER_SURRENDER_STR ] );
|
||||
else
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[PRISONER_TALK_STR] );
|
||||
@@ -11186,13 +11212,14 @@ void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
!pSoldier->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
{
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[PRISONER_DISTRACT_STR] );
|
||||
wcscpy( gzUserDefinedButton[3], TacticalStr[gSkillTraitValues.fCOTurncoats == TRUE ? PRISONER_RECRUIT_TURNCOAT_STR : PRISONER_TALK_STR] );
|
||||
}
|
||||
else
|
||||
{
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[PRISONER_TALK_STR] );
|
||||
wcscpy( gzUserDefinedButton[3], TacticalStr[PRISONER_TALK_STR] );
|
||||
}
|
||||
|
||||
wcscpy( gzUserDefinedButton[3], TacticalStr[ PRISONER_TALK_STR ] );
|
||||
DoMessageBox( MSG_BOX_BASIC_MEDIUM_BUTTONS, TacticalStr[ PRISONER_OFFER_SURRENDER ], guiCurrentScreen, MSG_BOX_FLAG_GENERIC_FOUR_BUTTONS, PrisonerSurrenderMessageBoxCallBack, NULL );
|
||||
}
|
||||
|
||||
|
||||
@@ -18117,10 +18117,12 @@ BOOLEAN SOLDIERTYPE::CanUseSkill( INT8 iSkill, BOOLEAN fAPCheck, INT32 sGridNo )
|
||||
// - a non-profile, not-already-turncoat enemy soldier
|
||||
// - enemy team not aware of us
|
||||
// - valid disguise
|
||||
// - enough AP to talk
|
||||
{
|
||||
SOLDIERTYPE* pSoldier = SimpleFindSoldier( sGridNo, gsInterfaceLevel );
|
||||
if ( pSoldier
|
||||
&& InPositionForTurncoatAttempt( pSoldier->ubID ) )
|
||||
&& InPositionForTurncoatAttempt( pSoldier->ubID )
|
||||
&& (!fAPCheck || EnoughPoints( this, APBPConstants[AP_TALK], 0, FALSE ) ) )
|
||||
{
|
||||
canuse = TRUE;
|
||||
}
|
||||
@@ -18421,6 +18423,9 @@ STR16 SOLDIERTYPE::PrintSkillDesc( INT8 iSkill, INT32 sGridNo )
|
||||
swprintf( atStr, pTraitSkillsDenialStrings[TEXT_SKILL_DENIAL_STRATEGIC_SUSPICION] );
|
||||
wcscat( skilldescarray, atStr );
|
||||
|
||||
swprintf( atStr, pTraitSkillsDenialStrings[TEXT_SKILL_DENIAL_X_AP], APBPConstants[AP_TALK] );
|
||||
wcscat( skilldescarray, atStr );
|
||||
|
||||
break;
|
||||
|
||||
case SKILLS_ACTIVATE_TURNCOATS:
|
||||
@@ -21552,6 +21557,10 @@ void SOLDIERTYPE::OrderAllTurnCoatToSwitchSides()
|
||||
SOLDIERTYPE *pSoldier;
|
||||
INT32 cnt = gTacticalStatus.Team[ENEMY_TEAM].bFirstID;
|
||||
|
||||
// rftr: force the player to enter turn-based combat. this function already includes a check to see if we're already in combat, so no harm calling this.
|
||||
// this also prevents a hang when activating a sector with 100% turncoats
|
||||
EnterCombatMode(OUR_TEAM);
|
||||
|
||||
// run through list
|
||||
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[ENEMY_TEAM].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
@@ -23200,8 +23209,6 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
//lal
|
||||
// ATE; Check for normal civs...
|
||||
|
||||
BOOLEAN apsDeducted = FALSE;
|
||||
|
||||
if ( GetCivType( pTSoldier ) != CIV_TYPE_NA )
|
||||
{
|
||||
//lal
|
||||
@@ -23212,18 +23219,17 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deduct points from our guy....
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
apsDeducted = TRUE;
|
||||
|
||||
// Flugente: if we are talking to an enemy, we have the option to offer them surrender...
|
||||
if ( (gGameExternalOptions.fEnemyCanSurrender || gGameExternalOptions.fPlayerCanAsktoSurrender) && pTSoldier->CanBeCaptured( ) )
|
||||
// Flugente: if we are talking to an enemy, we have the option to offer them surrender... we can also ask them to become a turncoat
|
||||
if ( (gSkillTraitValues.fCOTurncoats || gGameExternalOptions.fEnemyCanSurrender || gGameExternalOptions.fPlayerCanAsktoSurrender) && pTSoldier->CanBeCaptured( ) )
|
||||
{
|
||||
// AP costs are handled inside the callback (PrisonerSurrenderMessageBoxCallBack)
|
||||
HandleSurrenderOffer( pTSoldier );
|
||||
return(FALSE);
|
||||
}
|
||||
else if ( pTSoldier->sNonNPCTraderID > 0 )
|
||||
{
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
UINT8 ubTownID = StrategicMap[CALCULATE_STRATEGIC_INDEX( pTSoldier->sSectorX, pTSoldier->sSectorY )].bNameId;
|
||||
|
||||
// not possible if this guy is hostile towards us
|
||||
@@ -23251,6 +23257,7 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
// if we passed the above check, we can trade
|
||||
else
|
||||
{
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
EnterShopKeeperInterfaceScreen_NonNPC( pTSoldier->sNonNPCTraderID, pTSoldier->ubID );
|
||||
}
|
||||
|
||||
@@ -23258,6 +23265,8 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
}
|
||||
else
|
||||
{
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
// Flugente: if this guy is a potential volunteer, we might be able to sway him
|
||||
HandleVolunteerRecruitment( this, pTSoldier );
|
||||
|
||||
@@ -23267,12 +23276,7 @@ BOOLEAN SOLDIERTYPE::PlayerSoldierStartTalking( UINT8 ubTargetID, BOOLEAN fValid
|
||||
}
|
||||
}
|
||||
|
||||
// WANNE: This fixes the bug, that APs for talking are not always deducted.
|
||||
if ( !apsDeducted )
|
||||
{
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
apsDeducted = TRUE;
|
||||
}
|
||||
DeductPoints( this, sAPCost, 0, UNTRIGGERED_INTERRUPT );
|
||||
|
||||
// Are we an EPC that is being escorted?
|
||||
if ( pTSoldier->ubProfile != NO_PROFILE && pTSoldier->ubWhatKindOfMercAmI == MERC_TYPE__EPC )
|
||||
|
||||
@@ -1113,6 +1113,7 @@ enum
|
||||
PRISONER_OFFER_SURRENDER_STR,
|
||||
PRISONER_DISTRACT_STR,
|
||||
PRISONER_TALK_STR,
|
||||
PRISONER_RECRUIT_TURNCOAT_STR,
|
||||
|
||||
// sevenfm: new disarm trap dialog, new messages for wrong mines when arming
|
||||
DISARM_DIALOG_DISARM,
|
||||
|
||||
@@ -4060,6 +4060,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"我方缴械投降", //L"Offer surrender",
|
||||
L"转移", //L"Distract",
|
||||
L"交谈",
|
||||
L"招募被策反的敌军", //L"Recruit turncoat", // TODO: confirm translation. copied from pTraitSkillsMenuStrings
|
||||
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
L"拆除陷阱",
|
||||
|
||||
@@ -4048,6 +4048,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Offer surrender",
|
||||
L"Distract", // TODO.Translate
|
||||
L"Talk",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// TODO.Translate
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
|
||||
@@ -4060,6 +4060,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Offer surrender",
|
||||
L"Distract",
|
||||
L"Talk",
|
||||
L"Recruit Turncoat",
|
||||
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
L"Disarm trap",
|
||||
|
||||
@@ -4053,6 +4053,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Votre reddition",
|
||||
L"Distract", // TODO.Translate
|
||||
L"Parler",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
L"Désamorcer le piège",
|
||||
|
||||
@@ -4081,6 +4081,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Kapitulation anbieten",
|
||||
L"Ablenken",
|
||||
L"Sprechen",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
L"Falle entschärfen",
|
||||
|
||||
@@ -4042,6 +4042,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Offer surrender",
|
||||
L"Distract", // TODO.Translate
|
||||
L"Talk",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// TODO.Translate
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
|
||||
@@ -4053,6 +4053,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Offer surrender",
|
||||
L"Distract", // TODO.Translate
|
||||
L"Talk",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// TODO.Translate
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
|
||||
@@ -4060,6 +4060,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Предложить сдаться",
|
||||
L"Distract", // TODO.Translate
|
||||
L"Переговоры",
|
||||
L"Recruit Turncoat", // TODO: translate
|
||||
|
||||
// added by sevenfm: disarm messagebox options, messages when arming wrong bomb
|
||||
L"Обезвредить",
|
||||
|
||||
Reference in New Issue
Block a user