diff --git a/(1) Community Patch/Database Changes/Defines/CoreDefineChanges.sql b/(1) Community Patch/Database Changes/Defines/CoreDefineChanges.sql index cde37166b9..f1c1577c9c 100644 --- a/(1) Community Patch/Database Changes/Defines/CoreDefineChanges.sql +++ b/(1) Community Patch/Database Changes/Defines/CoreDefineChanges.sql @@ -1008,7 +1008,7 @@ VALUES -- Camp Spawning ('BARBARIAN_CAMP_FIRST_TURN_PERCENT_PER_ERA', 0), -- VP Only: increase to target % of camps to spawn (for the initial spawning) per era. 10 = 1%. ('BARBARIAN_CAMP_ODDS_OF_NEW_CAMP_SPAWNING', 50), -- Community Patch Only: % chance of a new encampment spawning each turn - ('BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE', 1), -- # of tiles required in a landmass for a camp to spawn. + ('BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE', 2), -- # of tiles required in a landmass for a camp to spawn. ('BARBARIAN_CAMP_MINIMUM_DISTANCE_ANOTHER_CAMP', 4), -- Camps can't spawn within X tiles of another camp OR city. ('BARBARIAN_CAMP_MINIMUM_DISTANCE_RECENTLY_CLEARED_CAMP', 2), -- Min. distance between new camps and a recently cleared camp OR city. ('BARBARIAN_CAMP_CLEARED_MIN_TURNS_TO_RESPAWN', 15), -- Number of turns before a camp OR city is no longer considered recently cleared. Does not scale with game speed. diff --git a/(2) Vox Populi/Database Changes/DefineChanges.sql b/(2) Vox Populi/Database Changes/DefineChanges.sql index 4296131903..38e556a485 100644 --- a/(2) Vox Populi/Database Changes/DefineChanges.sql +++ b/(2) Vox Populi/Database Changes/DefineChanges.sql @@ -422,6 +422,9 @@ UPDATE Defines SET Value = 10 WHERE Name = 'BARBARIAN_CAMP_FIRST_TURN_PERCENT_OF -- Unit: 0.1% of eligible tiles UPDATE Defines SET Value = 5 WHERE Name = 'BARBARIAN_CAMP_FIRST_TURN_PERCENT_PER_ERA'; +-- # of tiles required in a landmass for a camp to spawn. +UPDATE Defines SET Value = 1 WHERE Name = 'BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE'; + -- Barbarian camps start spawning on this turn UPDATE Defines SET Value = 2 WHERE Name = 'BARBARIAN_INITIAL_SPAWN_TURN'; diff --git a/CvGameCoreDLL_Expansion2/CvBarbarians.cpp b/CvGameCoreDLL_Expansion2/CvBarbarians.cpp index 8ee7ce49d8..1f1625b6e9 100644 --- a/CvGameCoreDLL_Expansion2/CvBarbarians.cpp +++ b/CvGameCoreDLL_Expansion2/CvBarbarians.cpp @@ -732,7 +732,7 @@ void CvBarbarians::DoCamps() continue; // No camps on n-tile islands - if (pLoopPlot->getLandmass() == -1 || theMap.getLandmassById(pLoopPlot->getLandmass())->getNumTiles() <= /*1*/ GD_INT_GET(BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE)) + if (pLoopPlot->getLandmass() == -1 || theMap.getLandmassById(pLoopPlot->getLandmass())->getNumTiles() < /*2 in CP, 1 in VP*/ GD_INT_GET(BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE)) continue; // No camps on water, in owned territory, adjacent to owned territory, or in impassable tiles @@ -994,7 +994,7 @@ void CvBarbarians::SpawnBarbarianUnits(CvPlot* pPlot, int iNumUnits, BarbSpawnRe // ---------- SPAWNING RULES ---------- // // Plundered Trade Route - cannot use resources; can only spawn adjacent; no spawn cap - // Encampment - can use unowned resources within 3 tiles; can only spawn adjacent; spawn cap of 2 within 3 tiles + // Encampment - can use unowned resources within 3 tiles; can only spawn adjacent; spawn cap of 2 within 3 tiles; no ranged for encampment guards (except on 1-tile islands) // City - can use resources owned by the city and unowned resources within 3 tiles; can use the UU of the player the city was captured from; can only spawn adjacent; spawn cap of 4 within 3 tiles // Uprising or Partisans - can use resources owned by the player being revolted against as well as their UUs; no spawn cap // Horde Quest or City-State capture - can use any resources owned by the City-State; if militaristic and UU is land, can also use their UU; no spawn cap @@ -1150,8 +1150,18 @@ void CvBarbarians::SpawnBarbarianUnits(CvPlot* pPlot, int iNumUnits, BarbSpawnRe int iNumUnitsSpawned = 0; if (bSpawnOnPlot) { - UnitAITypes ePreferredType = (eReason == BARB_SPAWN_FROM_CITY || eReason == BARB_SPAWN_CITY_STATE_CAPTURE) ? UNITAI_RANGED : UNITAI_DEFENSE; - UnitTypes eUnit = GetRandomBarbarianUnitType(pPlot, ePreferredType, eUniqueUnitPlayer, vValidResources, CvSeeder::fromRaw(0x20a3b92c).mix(pPlot->GetPseudoRandomSeed())); + bool bAllowRanged = false; // Do not spawn ranged in empty encampments, except on 1-tile islands + bool bIsBarbCamp = false; + ImprovementTypes eCamp = (ImprovementTypes)GD_INT_GET(BARBARIAN_CAMP_IMPROVEMENT); + CvImprovementEntry* pkCampInfo = GC.getImprovementInfo(eCamp); + if (eCamp != NO_IMPROVEMENT && pkCampInfo) + { + bIsBarbCamp = pPlot->getImprovementType() == eCamp; + bAllowRanged = !bIsBarbCamp || (pPlot->getLandmass() != -1 && GC.getMap().getLandmassById(pPlot->getLandmass())->getNumTiles() == 1); + } + + UnitAITypes ePreferredType = (eReason == BARB_SPAWN_FROM_CITY || eReason == BARB_SPAWN_CITY_STATE_CAPTURE || (bIsBarbCamp && bAllowRanged)) ? UNITAI_RANGED : UNITAI_DEFENSE; + UnitTypes eUnit = GetRandomBarbarianUnitType(pPlot, ePreferredType, eUniqueUnitPlayer, vValidResources, bAllowRanged, CvSeeder::fromRaw(0x20a3b92c).mix(pPlot->GetPseudoRandomSeed())); CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eUnit); if (pkUnitInfo) { @@ -1247,7 +1257,7 @@ void CvBarbarians::SpawnBarbarianUnits(CvPlot* pPlot, int iNumUnits, BarbSpawnRe UnitAITypes eUnitAI = pSpawnPlot->isWater() ? UNITAI_ATTACK_SEA : UNITAI_FAST_ATTACK; // Pick a unit - UnitTypes eUnit = GetRandomBarbarianUnitType(pSpawnPlot, eUnitAI, eUniqueUnitPlayer, vValidResources, CvSeeder::fromRaw(0xea7311de).mix(pSpawnPlot->GetPseudoRandomSeed())); + UnitTypes eUnit = GetRandomBarbarianUnitType(pSpawnPlot, eUnitAI, eUniqueUnitPlayer, vValidResources, true, CvSeeder::fromRaw(0xea7311de).mix(pSpawnPlot->GetPseudoRandomSeed())); CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eUnit); if (pkUnitInfo) { @@ -1312,7 +1322,7 @@ void CvBarbarians::SpawnBarbarianUnits(CvPlot* pPlot, int iNumUnits, BarbSpawnRe } // -------------------------------------------------------------------------------- -UnitTypes CvBarbarians::GetRandomBarbarianUnitType(CvPlot* pPlot, UnitAITypes ePreferredUnitAI, PlayerTypes eUniqueUnitPlayer, vector& vValidResources, CvSeeder additionalSeed) +UnitTypes CvBarbarians::GetRandomBarbarianUnitType(CvPlot* pPlot, UnitAITypes ePreferredUnitAI, PlayerTypes eUniqueUnitPlayer, vector& vValidResources, bool bAllowRanged, CvSeeder additionalSeed) { CvPlayerAI& kBarbarianPlayer = GET_PLAYER(BARBARIAN_PLAYER); vector> candidates; @@ -1333,6 +1343,10 @@ UnitTypes CvBarbarians::GetRandomBarbarianUnitType(CvPlot* pPlot, UnitAITypes eP if (pkUnitInfo->GetCombat() <= 0 && pkUnitInfo->GetRangedCombat() <= 0) continue; + // No ranged if not allowed + if (!bAllowRanged && pkUnitInfo->GetRangedCombat() > 0) + continue; + const UnitClassTypes eUnitClass = (UnitClassTypes)pkUnitInfo->GetUnitClassType(); CvUnitClassInfo* pkUnitClassInfo = GC.getUnitClassInfo(eUnitClass); if (!pkUnitClassInfo) diff --git a/CvGameCoreDLL_Expansion2/CvBarbarians.h b/CvGameCoreDLL_Expansion2/CvBarbarians.h index a55fb847a9..ba0d1cfff8 100644 --- a/CvGameCoreDLL_Expansion2/CvBarbarians.h +++ b/CvGameCoreDLL_Expansion2/CvBarbarians.h @@ -50,7 +50,7 @@ class CvBarbarians static void SpawnBarbarianUnits(CvPlot* pPlot, int iNumUnits, BarbSpawnReason eReason); private: - static UnitTypes GetRandomBarbarianUnitType(CvPlot* pPlot, UnitAITypes ePreferredUnitAI, PlayerTypes eUniqueUnitPlayer, vector& vValidResources, CvSeeder additionalSeed); + static UnitTypes GetRandomBarbarianUnitType(CvPlot* pPlot, UnitAITypes ePreferredUnitAI, PlayerTypes eUniqueUnitPlayer, vector& vValidResources, bool bAllowRanged, CvSeeder additionalSeed); static short* m_aiBarbSpawnerCounter; static short* m_aiBarbSpawnerNumUnitsSpawned; }; diff --git a/CvGameCoreDLL_Expansion2/CvGlobals.cpp b/CvGameCoreDLL_Expansion2/CvGlobals.cpp index 8b0ad0d0f8..9d0ad25efe 100644 --- a/CvGameCoreDLL_Expansion2/CvGlobals.cpp +++ b/CvGameCoreDLL_Expansion2/CvGlobals.cpp @@ -1678,7 +1678,7 @@ CvGlobals::CvGlobals() : GD_INT_INIT(BALANCE_BARBARIAN_HEAL_RATE, 0), GD_INT_INIT(BARBARIAN_CAMP_FIRST_TURN_PERCENT_OF_TARGET_TO_ADD, 33), GD_INT_INIT(BARBARIAN_CAMP_FIRST_TURN_PERCENT_PER_ERA, 0), - GD_INT_INIT(BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE, 1), + GD_INT_INIT(BARBARIAN_CAMP_MINIMUM_ISLAND_SIZE, 2), GD_INT_INIT(BARBARIAN_CAMP_MINIMUM_DISTANCE_CAPITAL, 4), GD_INT_INIT(BARBARIAN_CAMP_MINIMUM_DISTANCE_ANOTHER_CAMP, 4), GD_INT_INIT(BARBARIAN_CAMP_MINIMUM_DISTANCE_RECENTLY_CLEARED_CAMP, 2),