Skip to content

Commit

Permalink
More war & demand logic improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
RecursiveVision committed Jul 7, 2024
1 parent e842ca1 commit f74b3f9
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ UPDATE Defines SET Value = 10 WHERE Name = 'OPINION_WEIGHT_ASKED_STOP_SPYING';
-- You made a trade demand of them!
UPDATE Defines SET Value = 20 WHERE Name = 'OPINION_WEIGHT_MADE_DEMAND_OF_US';
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_MADE_DEMAND_OF_US_SUBSEQUENT', 10; -- any after the first; must be a lesser penalty or equal to the initial value
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_MADE_DEMAND_YOU_NO_TAKE_DIVISOR', 200; -- decreases opinion weight if AI is not currently giving anything
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_MADE_DEMAND_BANKRUPT_MULTIPLIER', 200; -- increases opinion weight if AI is currently giving something AND is bankrupt (or will be soon)
INSERT INTO Defines (Name, Value) SELECT 'OPINION_WEIGHT_MADE_DEMAND_BANKRUPT_MULTIPLIER_TURNS', 20; -- max turns for AI "soon" bankruptcy multiplier (penalty gradually increases as turns to bankruptcy decrease)


-- //////////////////////////////////////
Expand Down
61 changes: 28 additions & 33 deletions CvGameCoreDLL_Expansion2/CvDealAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2899,20 +2899,25 @@ int CvDealAI::GetThirdPartyWarValue(bool bFromMe, PlayerTypes eOtherPlayer, Team

// No deals if there is a denouncement in either direction
CvDiplomacyAI* pOurDiploAI = GetPlayer()->GetDiplomacyAI();
CivApproachTypes eApproachTowardsAskingPlayer = pOurDiploAI->GetCivApproach(eOtherPlayer);
if (pOurDiploAI->IsDenouncedPlayer(eOtherPlayer) || pOurDiploAI->IsDenouncedByPlayer(eOtherPlayer))
return INT_MAX;

// No war deals with backstabbers - it's a trap!
if (pOurDiploAI->IsUntrustworthy(eOtherPlayer))
return INT_MAX;

// Minor Civ?
// Friendly towards Minor Civ?
CvDiplomacyAI* pDiploAI = kPlayerDeclaringWar.GetDiplomacyAI();
CivApproachTypes eMajorApproachTowardsWarPlayer = pDiploAI->GetCivApproach(eWithPlayer);
if (GET_PLAYER(eWithPlayer).isMinorCiv())
{
CivApproachTypes eMinorApproachTowardsWarPlayer = pDiploAI->GetCivApproach(eWithPlayer);
if (eMinorApproachTowardsWarPlayer == CIV_APPROACH_FRIENDLY)
if (eMajorApproachTowardsWarPlayer == CIV_APPROACH_FRIENDLY)
return INT_MAX;
}
// Afraid of Major Civ?
else if (GET_PLAYER(eWithPlayer).isMajorCiv())
{
if (eMajorApproachTowardsWarPlayer == CIV_APPROACH_AFRAID)
return INT_MAX;
}

Expand Down Expand Up @@ -2940,10 +2945,6 @@ int CvDealAI::GetThirdPartyWarValue(bool bFromMe, PlayerTypes eOtherPlayer, Team
if (!pDiploAI->IsWarSane(eWithPlayer))
return INT_MAX;

// Already planning a coop war against the target? then we aren't interested! (reduce the chance of a premature declaration...)
if (pDiploAI->GetGlobalCoopWarAgainstState(eWithPlayer) >= COOP_WAR_STATE_PREPARING)
return INT_MAX;

// Can't be too far away
if (kPlayerDeclaringWar.GetProximityToPlayer(eWithPlayer) < PLAYER_PROXIMITY_CLOSE)
return INT_MAX;
Expand Down Expand Up @@ -3001,6 +3002,17 @@ int CvDealAI::GetThirdPartyWarValue(bool bFromMe, PlayerTypes eOtherPlayer, Team
}
}

// Already planning a coop war against the target? then we aren't interested! (reduce the chance of a premature declaration...)
vector<PlayerTypes> vMyTeam = GET_TEAM(kPlayerDeclaringWar.getTeam()).getPlayers();
for (size_t i=0; i<vMyTeam.size(); i++)
{
if (!GET_PLAYER(vMyTeam[i]).isAlive() || !GET_PLAYER(vMyTeam[i]).isMajorCiv())
continue;

if (GET_PLAYER(vMyTeam[i]).GetDiplomacyAI()->GetGlobalCoopWarAgainstState(eWithPlayer) == COOP_WAR_STATE_PREPARING)
return INT_MAX;
}

// What does a basic unit cost these days, use that as a base
UnitTypes eUnit = kPlayerDeclaringWar.GetCompetitiveSpawnUnitType(true, true, true, true);
int iItemValue = eUnit != NO_UNIT ? pCapital->GetPurchaseCost(eUnit) : 100;
Expand All @@ -3021,50 +3033,29 @@ int CvDealAI::GetThirdPartyWarValue(bool bFromMe, PlayerTypes eOtherPlayer, Team
iItemValue /= 100;
}
// If not against a major competitor, don't accept if we don't like the other guy
else if (eApproachTowardsAskingPlayer < CIV_APPROACH_AFRAID)
else if (pDiploAI->GetCivApproach(eOtherPlayer) < CIV_APPROACH_AFRAID)
{
return INT_MAX;
}
}

// Modify for our feelings towards the player we're would go to war with
CivApproachTypes eMajorApproachTowardsWarPlayer = pDiploAI->GetCivApproach(eWithPlayer);
if (eMajorApproachTowardsWarPlayer == CIV_APPROACH_WAR)
{
iItemValue *= 75;
iItemValue /= 100;
}
else if (eMajorApproachTowardsWarPlayer <= CIV_APPROACH_HOSTILE && eApproachTowardsAskingPlayer >= CIV_APPROACH_AFRAID)
else if (eMajorApproachTowardsWarPlayer <= CIV_APPROACH_HOSTILE)
{
iItemValue *= 90;
iItemValue /= 100;
}
else if (eMajorApproachTowardsWarPlayer <= CIV_APPROACH_GUARDED && eApproachTowardsAskingPlayer == CIV_APPROACH_FRIENDLY)
else
{
iItemValue *= 125;
iItemValue /= 100;
}

// Modify for our feelings towards the asking player
switch (eApproachTowardsAskingPlayer)
{
case CIV_APPROACH_WAR:
case CIV_APPROACH_HOSTILE:
case CIV_APPROACH_DECEPTIVE:
case CIV_APPROACH_GUARDED:
break; // No change.
case CIV_APPROACH_FRIENDLY:
case CIV_APPROACH_AFRAID:
iItemValue *= 90;
iItemValue /= 100;
break;
case NO_CIV_APPROACH:
case CIV_APPROACH_NEUTRAL:
iItemValue *= 150;
iItemValue /= 100;
break;
}

return iItemValue;
}

Expand Down Expand Up @@ -4692,6 +4683,10 @@ void CvDealAI::DoAddItemsToThem(CvDeal* pDeal, PlayerTypes eOtherPlayer, int& iT
bBlockPermanentItems = !GC.getGame().IsPermanentForTemporaryTradingAllowed();
}

// If this is a demand, can't ask for permanent items, so don't try
if (pDeal->GetDemandingPlayer() != NO_PLAYER)
bBlockPermanentItems = true;

// Add items to the deal while the deal value is below the threshold value. Each item added increases the deal value. iThresholdValue should be 0 if we want to equalize the deal.
// We use a positive value for iThresholdValue if a previous attempt to equalize the deal using iThresholdValue=0 has failed and we're now trying to add items on both sides.
if (!bGoldOnly)
Expand Down Expand Up @@ -5502,7 +5497,7 @@ int CvDealAI::GetPotentialDemandValue(PlayerTypes eOtherPlayer, CvDeal* pDeal, i
return 0;
}

if (iTotalValue <= 0 || iTotalValue >= INT_MAX)
if (iTotalValue <= 0 || iTotalValue == INT_MAX)
{
return 0;
}
Expand Down
21 changes: 17 additions & 4 deletions CvGameCoreDLL_Expansion2/CvDealClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5394,9 +5394,13 @@ void CvGameDeals::DoCancelDealsBetweenTeams(TeamTypes eTeam1, TeamTypes eTeam2)
}
}

/// Deals between these two Players were interrupted (death or world congress sanctions)
/// Deals between these two Players were interrupted (war, death or world congress sanctions)
void CvGameDeals::DoCancelDealsBetweenPlayers(PlayerTypes eFromPlayer, PlayerTypes eToPlayer, bool bCancelPeaceTreaties)
{
// If deals were cancelled, AI should no longer be deterred from declaring war due to a recent accepted demand
GET_PLAYER(eFromPlayer).GetDiplomacyAI()->SetNumConsecutiveDemandsTheyAccepted(eToPlayer, 0);
GET_PLAYER(eToPlayer).GetDiplomacyAI()->SetNumConsecutiveDemandsTheyAccepted(eFromPlayer, 0);

DealList::iterator it;
DealList tempDeals;

Expand Down Expand Up @@ -5442,11 +5446,11 @@ void CvGameDeals::DoCancelDealsBetweenPlayers(PlayerTypes eFromPlayer, PlayerTyp
}
}

if(bSomethingChanged)
if (bSomethingChanged)
{
// Update UI if we were involved in the deal
PlayerTypes eActivePlayer = GC.getGame().getActivePlayer();
if(eFromPlayer == eActivePlayer || eToPlayer == eActivePlayer)
if (eFromPlayer == eActivePlayer || eToPlayer == eActivePlayer)
{
GC.GetEngineUserInterface()->setDirty(GameData_DIRTY_BIT, true);
}
Expand Down Expand Up @@ -6487,7 +6491,7 @@ bool CvGameDeals::IsReceivingItemsFromPlayer(PlayerTypes ePlayer, PlayerTypes eO
return false;
}

int CvGameDeals::GetDealValueWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, bool bEmbargoEvaluation)
int CvGameDeals::GetDealValueWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, bool bEmbargoEvaluation, bool bExcludeConcessions)
{
DealList::iterator iter;
DealList::iterator end = m_CurrentDeals.end();
Expand All @@ -6503,6 +6507,15 @@ int CvGameDeals::GetDealValueWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherP
if (iEndTurn <= GC.getGame().getGameTurn())
continue;

if (bExcludeConcessions)
{
if (iter->GetDemandingPlayer() != NO_PLAYER)
continue;

if (iter->IsPeaceTreatyTrade(ePlayer))
continue;
}

if (!bEmbargoEvaluation)
{
iVal += iter->GetGoldPerTurnTrade(eOtherPlayer) * (iter->GetEndTurn() - GC.getGame().getGameTurn());
Expand Down
2 changes: 1 addition & 1 deletion CvGameCoreDLL_Expansion2/CvDealClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ class CvGameDeals
uint GetNumHistoricDealsWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, uint iMaxCount = UINT_MAX);
std::vector<CvDeal*> GetRenewableDealsWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, uint iMaxCount = UINT_MAX, bool bOnlyCheckedDeals = false);
bool IsReceivingItemsFromPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, bool bMutual);
int GetDealValueWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, bool bEmbargoEvaluation);
int GetDealValueWithPlayer(PlayerTypes ePlayer, PlayerTypes eOtherPlayer, bool bEmbargoEvaluation, bool bExcludeConcessions);
int GetTurnsBeforeRegainingLuxury(PlayerTypes ePlayer, ResourceTypes eResource);
int GetDealGPTLostFromWar(PlayerTypes ePlayer, PlayerTypes eOtherPlayer);

Expand Down
Loading

0 comments on commit f74b3f9

Please sign in to comment.