diff --git a/Assets/CvGameCoreDLL.dll b/Assets/CvGameCoreDLL.dll index be3ebecd2..e059043bf 100644 Binary files a/Assets/CvGameCoreDLL.dll and b/Assets/CvGameCoreDLL.dll differ diff --git a/Assets/Python/AIParameters.py b/Assets/Python/AIParameters.py new file mode 100644 index 000000000..e69de29bb diff --git a/Assets/Python/BUG/BugEventManager.py b/Assets/Python/BUG/BugEventManager.py index 1c2954453..ef75bda12 100644 --- a/Assets/Python/BUG/BugEventManager.py +++ b/Assets/Python/BUG/BugEventManager.py @@ -103,7 +103,6 @@ import BugCore import BugData import BugUtil -import Modifiers import InputUtil import types @@ -432,7 +431,6 @@ def _handleInitBugEvent(self, eventType, argsList): import BugInit BugInit.init() - Modifiers.setup() self._handleDefaultEvent(eventType, argsList) def resetActiveTurn(self, argsList=None): diff --git a/Assets/Python/CityNameManager.py b/Assets/Python/CityNameManager.py index 6a5e76d7f..48e0c8bb2 100644 --- a/Assets/Python/CityNameManager.py +++ b/Assets/Python/CityNameManager.py @@ -1,7 +1,5 @@ -# Rhye's and Fall of Civilization: Europe - City naming and renaming management - from CvPythonExtensions import * -from Core import civilizations, get_data_from_upside_down_map +from Core import civilizations, get_data_from_upside_down_map, cities from CityMapData import CITIES_MAP from Events import handler @@ -9,16 +7,24 @@ @handler("cityBuilt") -def onCityBuilt(city): - assignName(city) +def on_city_built(city): + assign_name(city) @handler("cityAcquired") -def onCityAcquired(iOwner, iNewOwner, city): - renameCities(city, iNewOwner) +def on_city_acquired(iOwner, iNewOwner, city): + rename_cities(city, iNewOwner) + + +@handler("GameStart") +def on_game_start(): + # the WB file cannot handle special chars and long names properly + # some of the cities intentionally have different names though (compared to the CNM), for example some Kievan cities + for city in cities.majors().entities(): + rename_cities(city, city.getOwner()) -def assignName(city): +def assign_name(city): """Names a city depending on its plot""" iOwner = city.getOwner() if iOwner < civilizations().majors().len(): @@ -27,7 +33,7 @@ def assignName(city): city.setName(unicode(cityName), False) -def renameCities(city, iNewOwner): +def rename_cities(city, iNewOwner): """Renames a city depending on its owner""" if iNewOwner < civilizations().majors().len(): cityName = get_data_from_upside_down_map(CITIES_MAP, iNewOwner, city) @@ -35,7 +41,7 @@ def renameCities(city, iNewOwner): city.setName(unicode(cityName), False) -def lookupName(city, iPlayer): +def lookup_name(city, iPlayer): """Looks up a city name in another player's map""" if iPlayer < civilizations().majors().len(): cityName = get_data_from_upside_down_map(CITIES_MAP, iPlayer, city) diff --git a/Assets/Python/Civilizations.py b/Assets/Python/Civilizations.py index cfa13074a..8ece3f7f6 100644 --- a/Assets/Python/Civilizations.py +++ b/Assets/Python/Civilizations.py @@ -15,26 +15,13 @@ from LocationsData import CIV_CAPITAL_LOCATIONS from MiscData import REVEAL_DATE_TECHNOLOGY from RFCUtils import change_attitude_extra_between_civ -from Events import handler -from TimelineData import TIMELINE_TECH_MODIFIER gc = CyGlobalContext() -@handler("GameStart") -def setup(): - set_starting_turns() - set_tech_timeline_date() - - def set_starting_turns(): for civ in civilizations().drop(Civ.BARBARIAN): - gc.setStartingTurn(civ.id, civ.date.birth) - - -def set_tech_timeline_date(): - for tech, turn in TIMELINE_TECH_MODIFIER: - gc.setTimelineTechDateForTech(tech, year(turn)) + civ.player.setInitialBirthTurn(civ.date.birth) def set_starting_gold(): diff --git a/Assets/Python/Core.py b/Assets/Python/Core.py index 90a22401c..5cbcca0a0 100644 --- a/Assets/Python/Core.py +++ b/Assets/Python/Core.py @@ -982,6 +982,10 @@ def since(iTurn): return turn() - iTurn +def every(interval): + return turn() % turns(interval) == 0 + + class InfoCollection(EntitiesCollection): def __init__(self, info_class, *infos): super(InfoCollection, self).__init__(*infos) @@ -2323,7 +2327,7 @@ def get_scenario(): return Scenario.i1200AD -def get_scenario_start_years(scenario=None): +def get_scenario_start_year(scenario=None): """Return scenario start year given a scenario.""" if scenario is None: scenario = get_scenario() diff --git a/Assets/Python/Crusades.py b/Assets/Python/Crusades.py index 24fea7ee8..638824a2f 100644 --- a/Assets/Python/Crusades.py +++ b/Assets/Python/Crusades.py @@ -24,7 +24,7 @@ from Events import handler, popup_handler from PyUtils import percentage, percentage_chance, rand, choice from ProvinceMapData import PROVINCES_MAP -from CityNameManager import lookupName +from CityNameManager import lookup_name from RFCUtils import convertPlotCulture, getMaster, getUniqueUnit, isAVassal from StoredData import data import random @@ -1034,9 +1034,9 @@ def startCrusade(): if iTargetPlayer == iHuman: underCrusadeAttackPopup(pTargetCity.getName(), iLeader) elif player().isExisting(): - sCityName = lookupName(pTargetCity, Civ.POPE) + sCityName = lookup_name(pTargetCity, Civ.POPE) if sCityName == "Unknown": - sCityName = lookupName(pTargetCity, iLeader) + sCityName = lookup_name(pTargetCity, iLeader) sText = text( "TXT_KEY_CRUSADE_START", player(iLeader).getCivilizationAdjectiveKey(), @@ -1148,9 +1148,9 @@ def crusadeArrival(iActiveCrusade): crusadeMakeUnits((iChosenX, iChosenY), iActiveCrusade) if human() == iLeader: pTargetCity = gc.getMap().plot(iTX, iTY).getPlotCity() - sCityName = lookupName(pTargetCity, Civ.POPE) + sCityName = lookup_name(pTargetCity, Civ.POPE) if sCityName == "Unknown": - sCityName = lookupName(pTargetCity, iLeader) + sCityName = lookup_name(pTargetCity, iLeader) message( iLeader, text("TXT_KEY_CRUSADE_ARRIVAL", sCityName) + "!", diff --git a/Assets/Python/DynamicCivs.py b/Assets/Python/DynamicCivs.py index 953379757..cd5a06b34 100644 --- a/Assets/Python/DynamicCivs.py +++ b/Assets/Python/DynamicCivs.py @@ -3,6 +3,15 @@ @handler("BeginPlayerTurn") -def refresh_civ_name(iGameTurn, iPlayer): - if iPlayer < civilizations().majors().len(): - player(iPlayer).processCivNames() +def on_begin_player_turn(gameturn, player_id): + refresh_civ_name(player_id) + + +@handler("GameStart") +def on_game_start(): + for player_id in civilizations().majors(): + refresh_civ_name(player_id) + + +def refresh_civ_name(player_id): + player(player_id).processCivNames() diff --git a/Assets/Python/Events.py b/Assets/Python/Events.py index 5eff32e8a..934202169 100644 --- a/Assets/Python/Events.py +++ b/Assets/Python/Events.py @@ -19,13 +19,28 @@ def handler_func(args): return handler_decorator -def noop(*args, **kwargs): - pass - - def popup_handler(event_id): def handler_decorator(func): events.addCustomEvent(event_id, func.__name__, func, noop) return func return handler_decorator + + +def noop(*args, **kwargs): + pass + + +events.addEvent("firstCity") + + +@handler("cityAcquiredAndKept") +def firstCityOnCityAcquiredAndKept(iPlayer, city): + if city.isCapital(): + events.fireEvent("firstCity", city) + + +@handler("cityBuilt") +def firstCityOnCityBuilt(city): + if city.isCapital(): + events.fireEvent("firstCity", city) diff --git a/Assets/Python/Handlers.py b/Assets/Python/Handlers.py index 69544c104..3796e0fe0 100644 --- a/Assets/Python/Handlers.py +++ b/Assets/Python/Handlers.py @@ -1,7 +1,8 @@ # ruff: noqa: F401 -import ScreenHandler +import ScreensHandler import CityNameManager +import DynamicCivs import Civilizations import History import Messages @@ -22,6 +23,7 @@ import Religions import Resources import Resurrection +import Rise import RiseAndFall import Secession import Stability diff --git a/Assets/Python/Modifiers.py b/Assets/Python/Modifiers.py index 61e8bcd9e..f678612eb 100644 --- a/Assets/Python/Modifiers.py +++ b/Assets/Python/Modifiers.py @@ -1,8 +1,7 @@ from CvPythonExtensions import * -from Core import civilization, civilizations, log +from Core import civilizations, log, year from CoreTypes import ( Modifier, - Building, City, Civ, Civic, @@ -20,22 +19,37 @@ FaithPointBonusCategory, ) from MiscData import ( + BUILDING_PREFERENCES, DIPLOMACY_MODIFIERS, HISTORICAL_ENEMIES, GREAT_PROPHET_FAITH_POINT_BONUS, PROSECUTOR_UNITCLASS, ) -from TimelineData import DateTurn +from TimelineData import TIMELINE_TECH_MODIFIER, DateTurn from LocationsData import CITIES +from Events import handler gc = CyGlobalContext() +@handler("GameStart") +def setup_gamestart(): + log("RFCE: GameStart") + setup() + + +@handler("OnLoad") +def setup_on_load(): + log("RFCE: OnLoad") + setup() + + def setup(): set_modifiers() set_diplomacy_modifier() set_tech_timeline_modifier() - set_starting_workers_modifier() + set_tech_timeline_date() + set_starting_workers() set_initial_building() set_building_preferences() set_unique_powers() @@ -133,7 +147,7 @@ def set_diplomacy_modifier(): gc.setDiplomacyModifiers(civ1, civ2, value) -def set_starting_workers_modifier(): +def set_starting_workers(): for civ in civilizations().majors(): gc.setStartingWorkers(civ.id, civ.initial.workers) @@ -163,21 +177,8 @@ def set_building_preferences(): # the getUniqueBuilding function does not work, probably the util functions are not yet usable when these initial values are set # but in the .dll these values are only used for the civ-specific building of the given buildingclass, so we can these add redundantly for civ in civilizations().majors(): - gc.setBuildingPref(civ.id, Building.WALLS, 5) - gc.setBuildingPref(civ.id, Building.CASTLE, 7) - gc.setBuildingPref(civ.id, Building.MANOR_HOUSE, 5) - gc.setBuildingPref(civ.id, Building.COURTHOUSE, 5) - gc.setBuildingPref(civ.id, Building.NIGHT_WATCH, 3) - gc.setBuildingPref(civ.id, Building.MOROCCO_KASBAH, 5) - gc.setBuildingPref(civ.id, Building.MOSCOW_KREMLIN, 7) - gc.setBuildingPref(civ.id, Building.HUNGARIAN_STRONGHOLD, 7) - gc.setBuildingPref(civ.id, Building.SPANISH_CITADEL, 7) - gc.setBuildingPref(civ.id, Building.FRENCH_CHATEAU, 5) - gc.setBuildingPref(civ.id, Building.VENICE_NAVAL_BASE, 5) - gc.setBuildingPref(civ.id, Building.KIEV_VECHE, 5) - gc.setBuildingPref(civ.id, Building.HOLY_ROMAN_RATHAUS, 5) - gc.setBuildingPref(civ.id, Building.LITHUANIAN_VOIVODESHIP, 5) - gc.setBuildingPref(civ.id, Building.SWEDISH_TENNANT, 3) + for building, preference in BUILDING_PREFERENCES: + gc.setBuildingPref(civ.id, building, preference) for civ in civilizations(): ai_modifier = civ.ai.modifiers.get(Modifier.BUILDING_PREFERENCE) @@ -354,6 +355,11 @@ def set_religion_spread_factor(): gc.setReligionSpread(civ.id, religion, threshold) +def set_tech_timeline_date(): + for tech, turn in TIMELINE_TECH_MODIFIER: + gc.setTimelineTechDateForTech(tech, year(turn)) + + def set_religion_benefit(): # gc.setReligionBenefit( iReligion, iFP_(whatever it is), iParameter, iCap ) # note that for powers iParameter = -1 means that this religion doesn't have this power (-1 is the default) @@ -427,7 +433,7 @@ def set_other_parameters(): # 3Miro: Psycho AI cheat, this will make Ottoman AI think it can win battles vs Constantinople at 90/100 rate # it will also actually boost the Ottoman's odds (actually lower the defenders chance by 20 percent), but only when attacking Constantinople - gc.setPsychoAICheat(Civ.OTTOMAN, *civilization(Civ.BYZANTIUM).location.capital) + gc.setPsychoAICheat(Civ.OTTOMAN, *CITIES[City.CONSTANTINOPLE]) # 3Miro: this sets rules on how players can Vassalize, first two parameters are the players (we should probably keep this symmetric) # if the third parameter is -1: cannot Vassalize, 0: has to satisfy a condition (default), 1 can Vassalize without conditions @@ -453,7 +459,5 @@ def set_other_parameters(): ) gc.setPapalPlayer(Civ.POPE, Religion.CATHOLICISM) - gc.setAutorunHack(Unit.CATAPULT, 32, 0) # Autorun hack, sync with RNF module - # 3MiroMercs: set the merc promotion gc.setMercPromotion(Promotion.MERC) diff --git a/Assets/Python/RFCUtils.py b/Assets/Python/RFCUtils.py index a2a92b15e..e8acef2b2 100644 --- a/Assets/Python/RFCUtils.py +++ b/Assets/Python/RFCUtils.py @@ -959,6 +959,7 @@ def ownedCityPlots(tCoords, argsList): return False +# TODO replace with Stability.isImmune def collapseImmune(iCiv): # 3MiroUP: Emperor if gc.hasUP(iCiv, UniquePower.NO_COLLAPSE_IN_CORE_AND_NORMAL_AREAS): diff --git a/Assets/Python/Resurrection.py b/Assets/Python/Resurrection.py index 97cd0c9ae..efc24a70a 100644 --- a/Assets/Python/Resurrection.py +++ b/Assets/Python/Resurrection.py @@ -216,6 +216,8 @@ def resurectCiv(iDeadCiv): # Absinthe: resetting the original potential provinces, and adding special province changes on respawn (Cordoba) onRespawn(iDeadCiv) + pDeadCiv.setLastBirthTurn(iGameTurn) + # Absinthe: we shouldn't get a previous leader on respawn - would be changed to a newer one in a couple turns anyway # instead we have a random chance to remain with the leader before the collapse, or to switch to the next one leaders = civilization(iDeadCiv).leaders[LeaderType.LATE] diff --git a/Assets/Python/Rise.py b/Assets/Python/Rise.py new file mode 100644 index 000000000..4802a545f --- /dev/null +++ b/Assets/Python/Rise.py @@ -0,0 +1,8 @@ +from Core import get_scenario_start_turn, game +import CvScreensInterface + + +# @handler("BeginGameTurn") +def showDawnOfMan(iGameTurn): + if iGameTurn == get_scenario_start_turn() and game.getAIAutoPlay() > 0: + CvScreensInterface.dawnOfMan.interfaceScreen() diff --git a/Assets/Python/RiseAndFall.py b/Assets/Python/RiseAndFall.py index 1b9fa1cfc..c3a438ad2 100644 --- a/Assets/Python/RiseAndFall.py +++ b/Assets/Python/RiseAndFall.py @@ -10,6 +10,7 @@ create_starting_workers, set_starting_diplomacy_1200AD, set_starting_faith, + set_starting_turns, ) from Consts import MessageData from Core import ( @@ -94,6 +95,7 @@ @handler("GameStart") def setup(): + set_starting_turns() setEarlyLeaders() if get_scenario() == Scenario.i500AD: diff --git a/Assets/Python/Setup.py b/Assets/Python/Setup.py index b41db2a2a..f6f4e3082 100644 --- a/Assets/Python/Setup.py +++ b/Assets/Python/Setup.py @@ -1,10 +1,8 @@ from CvPythonExtensions import CyGlobalContext -from CityNameManager import renameCities -from CoreTypes import Civ, Scenario, Area, AreaType +from CoreTypes import Area, AreaType from Events import handler from Core import ( civilizations, - get_scenario, get_data_from_upside_down_map, get_data_from_province_map, location, @@ -12,7 +10,6 @@ plot as _plot, location as _location, plots, - cities, ) from LocationsData import LAKE_LOCATIONS from CityMapData import CITIES_MAP @@ -43,8 +40,6 @@ def setup(): update_province_id() update_city_name() update_lake_id() - rename_cities_1200AD() - refresh_dynamic_civ_name() log("RFCE: Setup.setup()") @@ -112,18 +107,3 @@ def set_vizualization_areas(): # hold down the alt key, and hover over the map gc.setCoreToPlot(gc.getDefineINT("ENABLE_SPAWN_AREA_DISPLAY")) gc.setNormalToPlot(gc.getDefineINT("ENABLE_RESPAWN_AREA_DISPLAY")) - - -def rename_cities_1200AD(): - # Absinthe: rename cities on the 1200AD scenario - the WB file cannot handle special chars and long names properly - # some of the cities intentionally have different names though (compared to the CNM), for example some Kievan cities - # thus it's only set for Hungary for now, we can add more civs/cities later on if there are naming issues - if get_scenario() == Scenario.i1200AD: - for city in cities.owner(Civ.HUNGARY).entities(): - renameCities(city, Civ.HUNGARY) - - -def refresh_dynamic_civ_name(): - # Absinthe: refresh Dynamic Civ Names for all civs on the initial turn of the given scenario - for iPlayer in civilizations().majors().ids(): - gc.getPlayer(iPlayer).processCivNames() diff --git a/Assets/Python/data/MiscData.py b/Assets/Python/data/MiscData.py index 480180469..f329b55f2 100644 --- a/Assets/Python/data/MiscData.py +++ b/Assets/Python/data/MiscData.py @@ -147,6 +147,24 @@ (Civ.AUSTRIA, Civ.GERMANY, 10), ] +BUILDING_PREFERENCES = [ + (Building.WALLS, 5), + (Building.CASTLE, 7), + (Building.MANOR_HOUSE, 5), + (Building.COURTHOUSE, 5), + (Building.NIGHT_WATCH, 3), + (Building.MOROCCO_KASBAH, 5), + (Building.MOSCOW_KREMLIN, 7), + (Building.HUNGARIAN_STRONGHOLD, 7), + (Building.SPANISH_CITADEL, 7), + (Building.FRENCH_CHATEAU, 5), + (Building.VENICE_NAVAL_BASE, 5), + (Building.KIEV_VECHE, 5), + (Building.HOLY_ROMAN_RATHAUS, 5), + (Building.LITHUANIAN_VOIVODESHIP, 5), + (Building.SWEDISH_TENNANT, 3), +] + MODNET_EVENTS = { "CHANGE_COMMERCE_PERCENT": 1200, } diff --git a/Assets/Python/screens/CvInfoScreen.py b/Assets/Python/screens/CvInfoScreen.py index 133807fc0..72a1df6aa 100644 --- a/Assets/Python/screens/CvInfoScreen.py +++ b/Assets/Python/screens/CvInfoScreen.py @@ -7,7 +7,7 @@ from CvPythonExtensions import * from Civilizations import has_date_revealed from CoreTypes import Scenario -from Core import colortext, get_scenario, get_scenario_start_years, is_independent_civ, text, turn +from Core import colortext, get_scenario, get_scenario_start_year, is_independent_civ, text, turn import CvUtil import string @@ -3284,7 +3284,7 @@ def determineCityData(self): # Absinthe: top5 city foundation text if has_date_revealed(): - if iTurnYear <= get_scenario_start_years(): + if iTurnYear <= get_scenario_start_year(): if get_scenario() == Scenario.i500AD: szTurnFounded = text("TXT_KEY_FOUNDED_BEFORE_500AD") else: @@ -3292,7 +3292,7 @@ def determineCityData(self): else: szTurnFounded = text("TXT_KEY_TIME_AD", iTurnYear) else: - if iTurnYear <= get_scenario_start_years(): + if iTurnYear <= get_scenario_start_year(): szTurnFounded = text("TXT_KEY_FOUNDED_BEFORE_ERA") elif iTurnYear >= 1500: szTurnFounded = text("TXT_KEY_ERA_RENAISSANCE") @@ -3834,7 +3834,7 @@ def drawWondersList(self): # Absinthe: wonder foundation text iTurnYear = self.aiTurnYearBuilt[self.iActiveWonderCounter] if iTurnYear != -9999: # -9999 used for wonders in progress - if iTurnYear <= get_scenario_start_years(): + if iTurnYear <= get_scenario_start_year(): szTurnFounded = text("TXT_KEY_FOUNDED_BEFORE_START") else: if has_date_revealed(): diff --git a/Assets/Python/screens/ScreenHandler.py b/Assets/Python/screens/ScreensHandler.py similarity index 100% rename from Assets/Python/screens/ScreenHandler.py rename to Assets/Python/screens/ScreensHandler.py diff --git a/Assets/XML/GlobalDefinesVersion.xml b/Assets/XML/GlobalDefinesVersion.xml index 2a90c2849..a7e57d707 100644 --- a/Assets/XML/GlobalDefinesVersion.xml +++ b/Assets/XML/GlobalDefinesVersion.xml @@ -2,6 +2,6 @@ RFCE_MOD_VERSION - 1.6.5-2 + 1.6.5-3 diff --git a/ChangeLog.txt b/ChangeLog.txt index aacf7ca74..8896b44c0 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -14,6 +14,12 @@ You can find more details in the Manual and Reference folders in the mod. A copy Changes for RFCE enhancements: +v1.6.6: + +- Can't trade city with plague +- No financial trouble in the first 5 turns after spawn for AI +- Autoplay standby behavior and look has been improved (no more flashing when autoplay is actived) + v1.6.5: This release adds BUG and BULL mod - add BUG mod (v4.4) diff --git a/CvGameCoreDLL/CvCity.cpp b/CvGameCoreDLL/CvCity.cpp index c54e229a9..b36e27686 100644 --- a/CvGameCoreDLL/CvCity.cpp +++ b/CvGameCoreDLL/CvCity.cpp @@ -2026,27 +2026,6 @@ bool CvCity::canConstruct(BuildingTypes eBuilding, bool bContinue, bool bTestVis } // Absinthe: terrain type needed in BFC - //Rhye - start (embassy) - // 3Miro: when can build embassy - /*if (eBuilding >= NUM_BUILDINGS_PLAGUE) - { - if (getOwnerINLINE() >= NUM_MAJOR_PLAYERS) - return false; - if (getOwnerINLINE() == (PlayerTypes)((int)eBuilding - NUM_BUILDINGS_PLAGUE)) - return false; - if (!(GET_PLAYER(getOwnerINLINE()).canContact((PlayerTypes)((int)eBuilding - NUM_BUILDINGS_PLAGUE)))) - return false; - if ((GET_TEAM(getTeam()).isAtWar((TeamTypes)((int)eBuilding - NUM_BUILDINGS_PLAGUE)))) - return false; - if (GC.getGameINLINE().getGameTurn() <= startingTurn[eBuilding - NUM_BUILDINGS_PLAGUE] + 2) - return false; - int iEspionagePoints = GET_TEAM(getTeam()).getEspionagePointsAgainstTeam((TeamTypes)((int)eBuilding - NUM_BUILDINGS_PLAGUE)); - int iCost = 10; - if (iEspionagePoints < iCost) - return false; - }*/ - //Rhye - end - if (!bTestVisible) { if (!bContinue) @@ -11656,10 +11635,7 @@ void CvCity::setNumRealBuildingTimed(BuildingTypes eIndex, int iNewValue, bool b for (iI = 0; iI < MAX_PLAYERS; iI++) { - if ((GET_PLAYER((PlayerTypes)iI).isAlive()) && - (GC.getGameINLINE().getGameTurn() >= - startingTurn[GC.getGameINLINE() - .getActivePlayer()])) // Absinthe: no wonder built message during autoplay + if (GET_PLAYER((PlayerTypes)iI).isAlive()) { if (isRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false)) { diff --git a/CvGameCoreDLL/CvCityAI.cpp b/CvGameCoreDLL/CvCityAI.cpp index 52840ca84..ca83e98e7 100644 --- a/CvGameCoreDLL/CvCityAI.cpp +++ b/CvGameCoreDLL/CvCityAI.cpp @@ -9873,7 +9873,7 @@ void CvCityAI::AI_updateWorkersNeededHere() } // 3MiroAI: make the AI aware of the incomming starting workers - if (isCapital() && GC.getGameINLINE().getGameTurn() < startingTurn[getOwnerINLINE()] + 3) + if (isCapital() && GC.getGameINLINE().getGameTurn() < GET_PLAYER(getOwnerINLINE()).getLastBirthTurn() + getTurns(3)) { iWorkersHave += startingWorkers[getOwnerINLINE()]; }; diff --git a/CvGameCoreDLL/CvEnums.h b/CvGameCoreDLL/CvEnums.h index f9e9b0a0a..69a8bdca9 100644 --- a/CvGameCoreDLL/CvEnums.h +++ b/CvGameCoreDLL/CvEnums.h @@ -2837,6 +2837,8 @@ enum CivilopediaWidgetShowTypes // Absinthe: scenario types and identification enum ScenarioTypes { + NO_SCENARIO = -1, + SCENARIO_500AD, SCENARIO_1200AD, NUM_SCENARIO_TYPES, diff --git a/CvGameCoreDLL/CvGame.cpp b/CvGameCoreDLL/CvGame.cpp index 6edba4d15..7825a84ba 100644 --- a/CvGameCoreDLL/CvGame.cpp +++ b/CvGameCoreDLL/CvGame.cpp @@ -2198,14 +2198,11 @@ void CvGame::update() if (getTurnSlice() == 0) { - // Absinthe: disable autosave during autoplay - if ((GC.getDefineINT("NO_AUTOSAVE_DURING_AUTOPLAY") == 0) || - ((getGameTurn() > 0) && !(getGameTurn() < startingTurn[getActivePlayer()]))) + // edead: disable autosave during autoplay + if (GC.getDefineINT("NO_AUTOSAVE_DURING_AUTOPLAY") == 0 || (getGameTurn() > 0 && getAIAutoPlay() == 0)) { gDLL->getEngineIFace()->AutoSave(true); } - // Absinthe: end - //gDLL->getEngineIFace()->AutoSave(true); } if (getNumGameTurnActive() == 0) @@ -2230,7 +2227,7 @@ void CvGame::update() testAlive(); - if ((getAIAutoPlay() == 0) && !(gDLL->GetAutorun()) && GAMESTATE_EXTENDED != getGameState()) + if ((getAIAutoPlay() == 0) && !(gDLL->GetAutorun()) /*&& GAMESTATE_EXTENDED != getGameState()*/) { if (countHumanPlayersAlive() == 0) { @@ -2246,50 +2243,16 @@ void CvGame::update() gDLL->getInterfaceIFace()->setInAdvancedStart(true); gDLL->getInterfaceIFace()->setWorldBuilder(true); } - /* Absinthe: disabling old code start - //Rhye - start switch - Version B (late human starts) - int iHuman = MAX_PLAYERS; - for (int iI = 0; iI < MAX_CIV_PLAYERS; iI++) - { - if (GET_PLAYER((PlayerTypes)iI).isAlive()) - { - if (GET_PLAYER((PlayerTypes)iI).isHuman()) - { - iHuman = iI; - break; - } - } - } - // 3Miro - if ( (iHuman > -1) && (iHuman 0 ){ - if ( getGameTurn() == 0 ){ - setAIAutoPlay(1); - }else if ( getGameTurn() <= startingTurn[iHuman] ){ - setAIAutoPlayCatapult(1); - }; - }; - }; - */ //Absinthe: disabling old code end - // Absinthe: identify the active scenario - int iScenarioStartTurn = 0; // 500 AD - if (getScenario() == SCENARIO_1200AD) + if (getGameTurn() == getScenarioStartTurn() && + GET_PLAYER(getActivePlayer()).getInitialBirthTurn() > getScenarioStartTurn()) { - iScenarioStartTurn = 200; // 1200 AD - } - - // Absinthe: start Rhye's AIAutoPlay - int iHuman = getActivePlayer(); - if (startingTurn[iHuman] > iScenarioStartTurn) - { - if (getGameTurn() == iScenarioStartTurn) - { - setAIAutoPlay(1); - } - else if (getGameTurn() <= startingTurn[iHuman]) + int iInitialBirthTurn = GET_PLAYER(getActivePlayer()).getInitialBirthTurn(); + int iScenarioStartTurn = getScenarioStartTurn(); + int iTurnsUntilBirth = iInitialBirthTurn - iScenarioStartTurn; + if (iTurnsUntilBirth > 0) { - setAIAutoPlayCatapult(1); + setAIAutoPlay(iTurnsUntilBirth); } } } @@ -3457,9 +3420,7 @@ void CvGame::reviveActivePlayer() //Speed: End Modify //Rhye - end - GET_PLAYER(getActivePlayer()) - .initUnit(((UnitTypes)iAutorunUnit), iAutorunX, - iAutorunY); //Rhye: catapult // Absinthe: coordinates handled in RiseAndFall.py and RFCEBalance.py + GET_PLAYER(getActivePlayer()).verifyAlive(); } } @@ -4009,107 +3970,6 @@ void CvGame::setAIAutoPlay(int iNewValue) } } -//Rhye - start -void CvGame::setAIAutoPlayCatapult(int iNewValue) -{ - int iOldValue; - int iX, iY; - - iOldValue = getAIAutoPlay(); - - if (iOldValue != iNewValue) - { - m_iAIAutoPlay = std::max(0, iNewValue); - - if ((iOldValue == 0) && (getAIAutoPlay() > 0)) - { - CvPlot *pPlot = GC.getMapINLINE().plotINLINE(iAutorunX, iAutorunY); // 3Miro: the plot - if (pPlot->isUnit()) - { - GC.getMapINLINE() - .plotINLINE(iAutorunX, iAutorunY) - ->getUnitByIndex(0) - ->kill(false); // 3Miro catapult coordinates - for (int iI = 0; iI < MAX_PLAYERS; iI++) - { - if (GET_PLAYER((PlayerTypes)iI).isHuman()) - { - iX = iAutorunX; - iY = iAutorunY; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX + 1; - iY = iAutorunY; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX; - iY = iAutorunY + 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX - 1; - iY = iAutorunY; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX; - iY = iAutorunY - 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX + 1; - iY = iAutorunY + 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX + 1; - iY = iAutorunY - 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX - 1; - iY = iAutorunY + 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - iX = iAutorunX - 1; - iY = iAutorunY - 1; - if ((iX >= 0) && (iX < EARTH_X) && (iY >= 0) && (iY < EARTH_Y)) - { - GC.getMapINLINE().plotINLINE(iX, iY)->setRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false, false, - NO_TEAM, true); - } - break; // Absinthe: if it was already set for the human player, no reason to continue - } - } - } - else - { - logMsg("NO UNIT IN %d %d!!!", iAutorunX, iAutorunY); //Rhye - } - } - } -} -//Rhye - end - void CvGame::changeAIAutoPlay(int iChange) { setAIAutoPlay(getAIAutoPlay() + iChange); @@ -5533,10 +5393,7 @@ void CvGame::setHolyCity(ReligionTypes eIndex, CvCity *pNewValue, bool bAnnounce for (iI = 0; iI < MAX_PLAYERS; iI++) { - if ((GET_PLAYER((PlayerTypes)iI).isAlive()) && - (GC.getGameINLINE().getGameTurn() >= - startingTurn[GC.getGameINLINE() - .getActivePlayer()])) // Absinthe: no religion founded message during autoplay + if (GET_PLAYER((PlayerTypes)iI).isAlive()) { if (pHolyCity->isRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false)) { @@ -5788,11 +5645,13 @@ void CvGame::doTurn() int iLoopPlayer; int iI; + // TODO rewrite this with m_bTurnPlayed //Rhye - start for (iI = 0; iI < MAX_PLAYERS; iI++) turnPlayed[iI] = 0; //Rhye - end + // TODO clean this // 3MiroProvinces: Culture Immune Provinces (countdown) for (iI = 0; iI < MAX_NUM_PROVINCES; iI++) { @@ -5804,10 +5663,10 @@ void CvGame::doTurn() // 3Miro: Culture hack withinSpawnDate = false; - iI = getGameTurn(); for (iLoopPlayer = 0; iLoopPlayer < NUM_MAJOR_PLAYERS; iLoopPlayer++) { - if ((iI >= startingTurn[iLoopPlayer] - 1) && (iI < startingTurn[iLoopPlayer] + 2)) + if (getGameTurn() < GET_PLAYER((PlayerTypes)iLoopPlayer).getLastBirthTurn() + getTurns(2) && + getGameTurn() >= GET_PLAYER((PlayerTypes)iLoopPlayer).getLastBirthTurn() - getTurns(1)) { withinSpawnDate = true; }; @@ -5825,22 +5684,6 @@ void CvGame::doTurn() }; }; - /*GC.getGameINLINE().logMsg(" TURN=%d ",getGameTurn() ); - CvPlot *ppPlot = GC.getMapINLINE().plot( 76, 28 ); - GC.getGameINLINE().logMsg(" Owner = %d ", ppPlot ->getOwnerINLINE() ); - bool bByzB = ppPlot ->canBuild( (BuildTypes) 2, (PlayerTypes) 1, true ); - bool bBulB = ppPlot ->canBuild( (BuildTypes) 2, (PlayerTypes) 4, true ); - if ( bByzB ){ - GC.getGameINLINE().logMsg(" Byz can Build " ); - }else{ - GC.getGameINLINE().logMsg(" Byz cannot Build " ); - }; - if ( bByzB ){ - GC.getGameINLINE().logMsg(" Bul can Build " ); - }else{ - GC.getGameINLINE().logMsg(" Bul cannot Build " ); - };*/ - // END OF TURN CvEventReporter::getInstance().beginGameTurn(getGameTurn()); @@ -5976,14 +5819,11 @@ void CvGame::doTurn() stopProfilingDLL(); - // Absinthe: disable autosave during autoplay - if ((GC.getDefineINT("NO_AUTOSAVE_DURING_AUTOPLAY") == 0) || - ((getGameTurn() > 0) && !(getGameTurn() < startingTurn[getActivePlayer()]))) + // edead: disable autosave during autoplay + if (GC.getDefineINT("NO_AUTOSAVE_DURING_AUTOPLAY") == 0 || (getGameTurn() > 0 && getAIAutoPlay() == 0)) { gDLL->getEngineIFace()->AutoSave(); } - // Absinthe: end - //gDLL->getEngineIFace()->AutoSave(); } void CvGame::doDeals() @@ -10103,185 +9943,3 @@ bool CvGame::safeMotherland(int iCiv) //if ( (GET_PLAYER((PlayerTypes)iCiv).getEverRespawned()) && (iCitiesOwned > 0) ) return true; return false; }; - -// Absinthe: unused in RFCE -/* -int CvGame::cityStabilityExpansion( int iPlayer, int iFCity ){ - // 3Miro: Note that this is Rhye's original scheme, we use provinces for Stability - CvCity *pCity; - int pl, x, y; - int iExp = 0; - int iLoop; - for ( pCity = GET_PLAYER((PlayerTypes)iPlayer).firstCity(&iLoop); pCity != NULL; pCity = GET_PLAYER((PlayerTypes)iPlayer).nextCity(&iLoop) ){ - x = pCity ->getX(); - y = pCity ->getY(); - for ( pl = 0; pl < NUM_MAJOR_PLAYERS; pl++ ){ - if ( (getGameTurn() > startingTurn[pl]) && (pl != iPlayer) ){ - //if( MiroBelongToNormal( pl, x, y ) && (settlersMaps[iPlayer][EARTH_Y-y-1][x] < 150 ) ){ - //if( MiroBelongToNormal( pl, x, y ) && (getSettlersMaps(iPlayer,EARTH_Y-y-1,x) < 150 ) ){ - if( MiroBelongToNormal( pl, x, y ) && (getSettlersMaps(iPlayer,EARTH_Y-y-1,x, "cityStabilityExpansion") < 150 ) ){ - iExp += iFCity; - }; - }; - }; - }; - return iExp; -}; - -// Absinthe: unused in RFCE -int CvGame::cityStabilityPenalty( int iPlayer, int iAnger, int iHealth, int iReligion, int iLarge, int iHurry, int iNoMilitary, int iWarW, int iFReligion, int iFCulture, int iPerCityCap ){ - int iNumCities, iLoop; - int iTCS=0, iCS=0; - int pl, rel; - CvCity *pCity; - iNumCities = GET_PLAYER((PlayerTypes)iPlayer).getNumCities(); - for ( pCity = GET_PLAYER((PlayerTypes)iPlayer).firstCity(&iLoop); pCity != NULL; pCity = GET_PLAYER((PlayerTypes)iPlayer).nextCity(&iLoop) ){ - iTCS = 0; - if ( !( GET_PLAYER((PlayerTypes)iPlayer).isCivic((CivicTypes)28) && pCity ->isOccupation() ) ){ - if ( pCity ->angryPopulation(0) > 0 ) iTCS += iAnger; - if ( pCity ->healthRate(false, 0) < 0 ) iTCS += iHealth; - if ( pCity ->getReligionBadHappiness() > 0 ) iTCS += iReligion; - if ( pCity ->getLargestCityHappiness() < 0 ) iTCS += iLarge; - if ( pCity ->getHurryAngerModifier() > 0 ) iTCS += iHurry; - if ( pCity ->getNoMilitaryPercentAnger() > 0 ) iTCS += iNoMilitary; - if ( pCity ->getWarWearinessPercentAnger() > 0 ) iTCS += iWarW; - - // Theocracy and Org. Religion // This shouldn't be here, exceptions for religious civics - if ( GET_PLAYER((PlayerTypes)iPlayer).isCivic((CivicTypes)21) || GET_PLAYER((PlayerTypes)iPlayer).isCivic((CivicTypes)22) ){ - // 3MiroUP - if ( UniquePowers[iPlayer * UP_TOTAL_NUM + UP_RELIGIOUS_TOLERANCE] > -1 ){ - for ( rel=0; rel < NUM_RELIGIONS; rel++ ){ - if ( pCity ->isHasReligion((ReligionTypes)rel) && ( rel != GET_PLAYER((PlayerTypes)iPlayer).getStateReligion() ) ){ - iTCS += iFReligion; - }; - }; - }; - }; - - for( pl = 0; plgetCulture((PlayerTypes)pl) > 0 ){ - if ( pCity ->getCulture((PlayerTypes)iPlayer) == 0 ){ - iTCS += iFCulture; - }else{ - if ( (pCity ->getCulture((PlayerTypes)pl)*100)/ (pCity ->getCulture((PlayerTypes)iPlayer) ) > 15 ){ - iTCS += iFCulture; - }; - }; - }; - }; - }; - }; - - iCS += std::max(iPerCityCap, iTCS); - }; - return iCS; -}; - -// Absinthe: unused in RFCE -void CvGame::calcLastOwned(){ - int x, y, i; - if ( lOwnedCities == NULL ) lOwnedCities = new int[NUM_ALL_PLAYERS_B]; - if ( lOwnedPlots == NULL ) lOwnedPlots = new int[NUM_ALL_PLAYERS_B]; - for ( i=0; igetOwner(); - if ( (iOwner >= 0)&&(iOwnerisHills() ) || (plot ->isFlatlands() ) ) ) { - //if ( settlersMaps[iOwner][EARTH_Y-y-1][x] < 90 ) lOwnedPlots[iOwner]++; - //if ( getSettlersMaps(iOwner,EARTH_Y-y-1,x) < 90 ) lOwnedPlots[iOwner]++; - if ( getSettlersMaps(iOwner,EARTH_Y-y-1,x,"calcLastOwned1") < 90 ) lOwnedPlots[iOwner]++; - if ( plot ->isCity() ){ - iCityOwner = plot ->getPlotCity() ->getOwner(); - for( i = 0; i startingTurn[i]+30) ){ - //if ( (settlersMaps[i][EARTH_Y-x-1][x] >= 400) && MiroBelongToCore( i, x, y ) ){ - //if ( (getSettlersMaps(i,EARTH_Y-x-1,x) >= 400) && MiroBelongToCore( i, x, y ) ){ - if ( (getSettlersMaps(i,EARTH_Y-y-1,x,"calcLastOwned2") >= 400) && MiroBelongToCore( i, x, y ) ){ - lOwnedCities[i]++; - }; - }; - }; - }; - }; - }; - }; -}; - -// Absinthe: unused in RFCE -void CvGame::damagePlot( int iPlayer, int iFoeDamage, int iBarbDamage, CvPlot *pPlot ){ - int i, N; - CvUnit *pUnit; - if ( pPlot ->getOwner() == iPlayer ){ - N = pPlot ->getNumUnits(); - for ( i=0; igetUnitByIndex(i); - if ( GET_TEAM( GET_PLAYER((PlayerTypes)iPlayer).getTeam() ).isAtWar( pUnit ->getTeam() ) ){ - if ( pUnit ->getOwner() == BARBARIAN ){ - pUnit ->setDamage( pUnit->getDamage() + iBarbDamage, (PlayerTypes) iPlayer ); - }else{ - pUnit ->setDamage( pUnit->getDamage() + iFoeDamage, (PlayerTypes) iPlayer ); - }; - }; - }; - }; -}; - -// Absinthe: unused in RFCE -void CvGame::damageFromBuilding( int iPlayer, int iBuilding, int iFoeDamage, int iBarbDamage ){ - - int iLoop; - CvCity* pCity; - CvPlot* pPlot; - int x, y, cityX, cityY; - - for ( pCity = GET_PLAYER((PlayerTypes)iPlayer).firstCity(&iLoop); pCity != NULL; pCity = GET_PLAYER((PlayerTypes)iPlayer).nextCity(&iLoop) ){ - if ( pCity ->hasBuilding((BuildingTypes)iBuilding) ){ - cityX = pCity ->getX(); - cityY = pCity ->getY(); - // do close range - for ( x = cityX -1; x<=cityX+1; x++ ){ - for ( y = cityY-1; y<=cityY+1; y++ ){ - if ( (x>=0)&&(x=0)&&(y=0)&&(x=0)&&(y=0)&&(x=0)&&(y=0)&&(x=0)&&(y=0)&&(x=0)&&(y 0) setDateStr(szString, iGameTurn, bSave, eCalendar, iStartYear, eSpeed); else if (GET_PLAYER(ePlayer).getCurrentEra() >= 3) szString = gDLL->getText("TXT_KEY_ERA_RENAISSANCE"); @@ -274,10 +273,6 @@ void CvGameTextMgr::setDateStrPlayer(CvWString &szString, int iGameTurn, bool bS szString = gDLL->getText("TXT_KEY_ERA_EARLY_MEDIEVAL"); if (bSave) szString = szString + " " + gDLL->getText("TXT_KEY_SAVEGAME_TURN", (iGameTurn)); - /*if (gDLL->getCurrentLanguage() == 0) - szString = szString + " " + gDLL->getText("TXT_KEY_SAVEGAME_TURN", (iGameTurn)); - else - szString = gDLL->getText("TXT_KEY_SAVEGAME_TURN", (iGameTurn));*/ } void CvGameTextMgr::setTimeStr(CvWString &szString, int iGameTurn, bool bSave) diff --git a/CvGameCoreDLL/CvPlayer.cpp b/CvGameCoreDLL/CvPlayer.cpp index 6eb265866..181d8f9fb 100644 --- a/CvGameCoreDLL/CvPlayer.cpp +++ b/CvGameCoreDLL/CvPlayer.cpp @@ -577,6 +577,10 @@ void CvPlayer::reset(PlayerTypes eID, bool bConstructorCall) /* UNOFFICIAL_PATCH END */ /************************************************************************************************/ + //Leoreth + m_iInitialBirthTurn = 0; + m_iLastBirthTurn = 0; + m_eID = eID; updateTeamType(); updateHuman(); @@ -2909,15 +2913,8 @@ void CvPlayer::doTurn() } // Absinthe: without this check, civics are set back to a 0 state after initialization in the 1st turn - for civs before the autoplay civ - // identify the active scenario - int iScenarioStartTurn = 0; // 500 AD - if (getScenario() == SCENARIO_1200AD) - { - iScenarioStartTurn = 200; // 1200 AD - } // enough to check on the first turn of the scenario - //if ( GC.getGameINLINE().getGameTurn() >= startingTurn[getID()] ) - if (GC.getGameINLINE().getGameTurn() != iScenarioStartTurn) + if (GC.getGameINLINE().getGameTurn() != getScenarioStartTurn()) { verifyCivics(); } @@ -4324,7 +4321,7 @@ bool CvPlayer::canTradeItem(PlayerTypes eWhoTo, TradeData item, bool bTestDenial if (getID() != PAPAL_PLAYER && eWhoTo != PAPAL_PLAYER) { // Absinthe: Don't even show city trading for the human player in the first 5 turns after spawn (avoid exploit with city gifting before the flip for additional units) - if (startingTurn[getID()] + 5 < GC.getGamePointer()->getGameTurn()) + if (GC.getGameINLINE().getGameTurn() - getLastBirthTurn() > getTurns(5)) { CvCity *pCityTraded = getCity(item.m_iData); @@ -4632,8 +4629,9 @@ DenialTypes CvPlayer::getTradeDenial(PlayerTypes eWhoTo, TradeData item) const { return DENIAL_ATTITUDE; }; + // Leoreth: recently spawned civs cannot become vassals // 3Miro: no vassals for 20 turns after spawn - if (startingTurn[getID()] + 20 < GC.getGamePointer()->getGameTurn()) + if (GC.getGameINLINE().getGameTurn() - getLastBirthTurn() > getTurns(20)) { return GET_TEAM(getTeam()).AI_vassalTrade(GET_PLAYER(eWhoTo).getTeam()); } @@ -10824,7 +10822,7 @@ void CvPlayer::setAlive(bool bNewValue) for (iI = 0; iI < MAX_PLAYERS; iI++) { - if (GET_PLAYER((PlayerTypes)iI).isAlive() && (GC.getGameINLINE().getGameTurn() >= startingTurn[GC.getGameINLINE().getActivePlayer()])) // Absinthe: no civ destroyed message during autoplay + if (GET_PLAYER((PlayerTypes)iI).isAlive()) { gDLL->getInterfaceIFace()->addHumanMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CIVDESTROYED", MESSAGE_TYPE_MAJOR_EVENT, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_WARNING_TEXT")); } @@ -10846,13 +10844,19 @@ void CvPlayer::verifyAlive() if (isAlive()) { + // TODO see https://github.com/dguenms/Dawn-of-Civilization/commit/50cda761aaebbc77c3d32b1b76085bf022ba7a9a + // if (!isHuman() && GC.getGameINLINE().getGameTurn() < getInitialBirthTurn()) + // { + // return; + // } + bKill = false; if (!bKill) { if (!isBarbarian()) { - if (getNumCities() == 0 && getAdvancedStartPoints() < 0) + if (getNumCities() == 0 /*&& getAdvancedStartPoints() < 0*/) { if ((getNumUnits() == 0) || (!(GC.getGameINLINE().isOption(GAMEOPTION_COMPLETE_KILLS)) && isFoundedFirstCity())) @@ -17343,6 +17347,11 @@ void CvPlayer::read(FDataStreamBase *pStream) //pStream->ReadString(m_szCivShort); //pStream->ReadString(m_szCivAdj); //Rhye (jdog) - end ----------------------- + + //Leoreth + pStream->Read(&m_iInitialBirthTurn); + pStream->Read(&m_iLastBirthTurn); + pStream->Read((int *)&m_eID); pStream->Read((int *)&m_ePersonalityType); pStream->Read((int *)&m_eCurrentEra); @@ -17853,6 +17862,11 @@ void CvPlayer::write(FDataStreamBase *pStream) //pStream->WriteString(m_szCivShort); //pStream->WriteString(m_szCivAdj); //Rhye (jdog) - end ----------------------- + + //Leoreth + pStream->Write(m_iInitialBirthTurn); + pStream->Write(m_iLastBirthTurn); + pStream->Write(m_eID); pStream->Write(m_ePersonalityType); pStream->Write(m_eCurrentEra); @@ -24445,3 +24459,25 @@ void CvPlayer::addReminder(int iGameTurn, CvWString szMessage) const CvMessageControl::getInstance().sendAddReminder(getID(), iGameTurn, szMessage); } // BUG - Reminder Mod - end + +int CvPlayer::getInitialBirthTurn() const +{ + return m_iInitialBirthTurn; +} + +void CvPlayer::setInitialBirthTurn(int iNewValue) +{ + m_iInitialBirthTurn = iNewValue; + + setLastBirthTurn(iNewValue); +} + +int CvPlayer::getLastBirthTurn() const +{ + return m_iLastBirthTurn; +} + +void CvPlayer::setLastBirthTurn(int iNewValue) +{ + m_iLastBirthTurn = iNewValue; +} diff --git a/CvGameCoreDLL/CvPlayer.h b/CvGameCoreDLL/CvPlayer.h index bbf3d152c..44e152606 100644 --- a/CvGameCoreDLL/CvPlayer.h +++ b/CvGameCoreDLL/CvPlayer.h @@ -1243,6 +1243,10 @@ class CvPlayer // Leoreth int getDomainFreeExperience(DomainTypes eDomainType) const; + int getInitialBirthTurn() const; + void setInitialBirthTurn(int iNewValue); + int getLastBirthTurn() const; + void setLastBirthTurn(int iNewValue); protected: // 3Miro: culture bonus to cities if the player has no StateReligion @@ -1403,6 +1407,11 @@ class CvPlayer bool m_bFoundedFirstCity; bool m_bStrike; bool m_bHuman; + + //Leoreth + int m_iInitialBirthTurn; + int m_iLastBirthTurn; + //Rhye (jdog) - start --------------------- CvWString m_szName; CvWString m_szCivDesc; diff --git a/CvGameCoreDLL/CvPlayerAI.cpp b/CvGameCoreDLL/CvPlayerAI.cpp index f315a76a2..70538fa62 100644 --- a/CvGameCoreDLL/CvPlayerAI.cpp +++ b/CvGameCoreDLL/CvPlayerAI.cpp @@ -3640,18 +3640,13 @@ bool CvPlayerAI::AI_avoidScience() const // XXX bool CvPlayerAI::AI_isFinancialTrouble() const { - //if (getCommercePercent(COMMERCE_GOLD) > 50) { - //Rhye - start - int iGameTurn = GC.getGameINLINE().getGameTurn(); - if (iGameTurn == startingTurn[getID()] || iGameTurn == startingTurn[getID()] + 1 || - iGameTurn == startingTurn[getID()] + 2) + // Leoreth: be generous with recently started civs + if (GC.getGameINLINE().getGameTurn() < getLastBirthTurn() + getTurns(5)) + { return false; - // 3Miro - /*if (!GET_PLAYER((PlayerTypes)EGYPT).isPlayable()) //late start condition - if (iGameTurn <= 153) - return false;*/ - //Rhye - end + } + int iNetCommerce = 1 + getCommerceRate(COMMERCE_GOLD) + getCommerceRate(COMMERCE_RESEARCH) + std::max(0, getGoldPerTurn()); /************************************************************************************************/ @@ -8179,6 +8174,11 @@ DenialTypes CvPlayerAI::AI_cityTrade(CvCity *pCity, PlayerTypes ePlayer) const } //Rhye - end + if (isHuman() && (pCity->getNumActiveBuilding((BuildingTypes)(BUILDING_PLAGUE)) > 0)) + { + return DENIAL_NO_GAIN; + } + // Absinthe: no city trading for the Pope and from the Pope if ((getID() == PAPAL_PLAYER) || (ePlayer == PAPAL_PLAYER)) { @@ -8186,8 +8186,8 @@ DenialTypes CvPlayerAI::AI_cityTrade(CvCity *pCity, PlayerTypes ePlayer) const } // Absinthe: don't enable city trading/gifting in the first 5 turns after spawn (avoid exploit for additional units with city gifting before the flip) - if (startingTurn[ePlayer] + 5 > GC.getGamePointer()->getGameTurn() && - startingTurn[ePlayer] <= GC.getGamePointer()->getGameTurn()) + if ((GC.getGameINLINE().getGameTurn() - GET_PLAYER(ePlayer).getLastBirthTurn() < getTurns(5)) && + (GET_PLAYER(ePlayer).getLastBirthTurn() <= GC.getGameINLINE().getGameTurn())) { return DENIAL_NO_GAIN; } @@ -12490,18 +12490,14 @@ void CvPlayerAI::AI_doCivics() } // Absinthe: AI shouldn't want a revolution in the first 10 turns after birth (wait for the potential city flips, initial conquests/settling, war declarations, and whatnot) - if (GC.getGameINLINE().getGameTurn() < startingTurn[getID()] + 10) + if (GC.getGameINLINE().getGameTurn() < getLastBirthTurn() + getTurns(10)) { return; } // Absinthe: end + // Absinthe: AI shouldn't want a revolution in the first 7 turns of the scenario either - int iScenarioStartTurn = 0; // 500 AD - if (getScenario() == SCENARIO_1200AD) - { - iScenarioStartTurn = 200; // 1200 AD - } - if (GC.getGameINLINE().getGameTurn() < iScenarioStartTurn + 7) + if (GC.getGameINLINE().getGameTurn() < getScenarioStartTurn() + getTurns(7)) { return; } @@ -15250,7 +15246,8 @@ bool CvPlayerAI::AI_disbandUnit(int iExpThreshold, bool bObsolete) } // Absinthe: prevent AI units from being disbanded for 20 turns after spawn - idea from SoI - if (getID() < NUM_MAJOR_PLAYERS && GC.getGame().getGameTurn() < startingTurn[getID()] + 20) + // TODO clean NUM_MAJOR_PLAYERS + if (getID() < NUM_MAJOR_PLAYERS && GC.getGame().getGameTurn() < getLastBirthTurn() + getTurns(20)) { return false; } diff --git a/CvGameCoreDLL/CvPlot.cpp b/CvGameCoreDLL/CvPlot.cpp index e80db2e6e..7b5e15778 100644 --- a/CvGameCoreDLL/CvPlot.cpp +++ b/CvGameCoreDLL/CvPlot.cpp @@ -7314,31 +7314,6 @@ void CvPlot::setCulture(PlayerTypes eIndex, int iNewValue, bool bUpdate, bool bU } else { - // 3Miro: Nasty bug expelling units from territory on flip, - // now if a plot is in someone's core, nobody gets culture there for 3 turns after spawn - /*if ( withinSpawnDate ){ - if ( (eIndex >= NUM_MAJOR_PLAYERS) || ( !MiroBelongToCore(eIndex,getX_INLINE(),getX_INLINE()) ) ){ - int iI; - bool inBirthAndCore = false; - for( iI = 0; iI < NUM_MAJOR_PLAYERS; iI++ ){ - if ( (startingTurn[iI]>=GC.getGameINLINE().getGameTurn()) && (startingTurn[iI]<=GC.getGameINLINE().getGameTurn()+3) && (getSettlersMaps( iI, getX_INLINE(), getX_INLINE(), NULL ) > 600) ){ - inBirthAndCore = true; - break; - } - }; - if ( inBirthAndCore ){ - m_aiCulture[eIndex] = 0; - - }else{ - m_aiCulture[eIndex] = iNewValue; - }; - }else{ - m_aiCulture[eIndex] = iNewValue; - }; - }else{ - m_aiCulture[eIndex] = iNewValue; - };*/ - //m_aiCulture[eIndex] = iNewValue; if (withinSpawnDate && iNewValue > getCulture(eIndex)) { if ((eIndex >= NUM_MAJOR_PLAYERS) || (!MiroBelongToCore(eIndex, getX_INLINE(), getX_INLINE()))) @@ -7348,7 +7323,8 @@ void CvPlot::setCulture(PlayerTypes eIndex, int iNewValue, bool bUpdate, bool bU int iGameTurn = GC.getGameINLINE().getGameTurn(); for (iI = 0; iI < NUM_MAJOR_PLAYERS; iI++) { - if ((iGameTurn >= startingTurn[iI] - 1) && (iGameTurn < startingTurn[iI] + 2) && + if ((iGameTurn >= GET_PLAYER((PlayerTypes)iI).getLastBirthTurn() - getTurns(1)) && + (iGameTurn < GET_PLAYER((PlayerTypes)iI).getLastBirthTurn() + getTurns(2)) && (MiroBelongToCore(iI, getX_INLINE(), getX_INLINE()))) { return; diff --git a/CvGameCoreDLL/CvRhyes.cpp b/CvGameCoreDLL/CvRhyes.cpp index 194d2ac09..1f73d0bff 100644 --- a/CvGameCoreDLL/CvRhyes.cpp +++ b/CvGameCoreDLL/CvRhyes.cpp @@ -5,7 +5,6 @@ // rhyes.cpp -int *startingTurn = NULL; int *turnPlayed = NULL; int *civSpreadFactor = NULL; @@ -133,11 +132,6 @@ int *historicalEnemyAIcheat = NULL; // and then only check that in CvPlot. We will set withinSpawnDate in CvGame.cpp bool withinSpawnDate = false; -// 3Miro: Autorun hack -int iAutorunUnit; -int iAutorunX; -int iAutorunY; - // 3Miro: Commerse from Building + Civic int iCivicBuildingCommerse1 = -1; int iCivicBuildingCommerse2 = -1; diff --git a/CvGameCoreDLL/CvRhyes.h b/CvGameCoreDLL/CvRhyes.h index 8cec2639e..0ef77e1a9 100644 --- a/CvGameCoreDLL/CvRhyes.h +++ b/CvGameCoreDLL/CvRhyes.h @@ -258,7 +258,6 @@ extern int MAX_NUM_TECHS; extern int NUM_BUILDINGS; // Plague is the last "building" #define BUILDING_PLAGUE (NUM_BUILDINGS - 1) -extern int *startingTurn; extern int *turnPlayed; // 3Miro: overkill but leave it extern int *civSpreadFactor; // 3Miro: includes major players, minor players, indeps and barbs @@ -353,12 +352,6 @@ extern int FAST_TERRAIN; // 3Miro: hack on the culture bug, see CvRhye.cpp extern bool withinSpawnDate; -// 3Miro: autorun hack (a unit is created and destroyed every turn for the Human player) -// we need a place to put the unit and a unit index -extern int iAutorunUnit; -extern int iAutorunX; -extern int iAutorunY; - // 3Miro: Commerce from Building + Civic extern int iCivicBuildingCommerse1; extern int iCivicBuildingCommerse2; diff --git a/CvGameCoreDLL/CvTeam.cpp b/CvGameCoreDLL/CvTeam.cpp index 99aeac826..4e0c6f8f4 100644 --- a/CvGameCoreDLL/CvTeam.cpp +++ b/CvGameCoreDLL/CvTeam.cpp @@ -1193,26 +1193,6 @@ bool CvTeam::canChangeWarPeace(TeamTypes eTeam, bool bAllowVassal) const bool CvTeam::canDeclareWar(TeamTypes eTeam) const { - - // 3MiroPAPAL: war with the pope - if (eTeam == PAPAL_PLAYER || getID() == PAPAL_PLAYER) - { - return false; - }; - - // 3Miro: Cannot Declare War for 5 turns after player spawn - variable exported into python - int iPlayer = GET_TEAM(eTeam).getLeaderID(); - // Absinthe: this originally meant that no wars at all in the first 5 turns after 500 AD, but now you can declare on indies and barbs anytime - if (eTeam < NUM_MAJOR_PLAYERS) - { - if (GC.getGameINLINE().getGameTurn() < startingTurn[iPlayer] + iPeaceTurnsAfterSpawn) - { - return false; - } - } - // Absinthe: end - // 3Miro: end - if (eTeam == getID()) { return false; @@ -1259,6 +1239,22 @@ bool CvTeam::canDeclareWar(TeamTypes eTeam) const return false; } + // Voigt: can't war with the pope + if (eTeam == PAPAL_PLAYER || getID() == PAPAL_PLAYER) + { + return false; + }; + + // Leoreth: protect recently spawned civs for ten turns to avoid early attack exploits + if (!GET_TEAM(eTeam).isMinorCiv() && !GET_TEAM(eTeam).isBarbarian()) + { + if (GC.getGameINLINE().getGameTurn() < + GET_PLAYER(GET_TEAM(eTeam).getLeaderID()).getLastBirthTurn() + getTurns(iPeaceTurnsAfterSpawn)) + { + return false; + } + } + if (GC.getUSE_CAN_DECLARE_WAR_CALLBACK()) { CyArgsList argsList; @@ -4933,10 +4929,7 @@ void CvTeam::changeProjectCount(ProjectTypes eIndex, int iChange) for (iI = 0; iI < MAX_PLAYERS; iI++) { - if ((GET_PLAYER((PlayerTypes)iI).isAlive()) && - (GC.getGameINLINE().getGameTurn() >= - startingTurn[GC.getGameINLINE() - .getActivePlayer()])) // Absinthe: no project completed message during autoplay + if (GET_PLAYER((PlayerTypes)iI).isAlive()) { //szBuffer = gDLL->getText("TXT_KEY_MISC_SOMEONE_HAS_COMPLETED", getName().GetCString(), GC.getProjectInfo(eIndex).getTextKeyWide()); //Rhye szBuffer = gDLL->getText("TXT_KEY_MISC_SOMEONE_HAS_COMPLETED", diff --git a/CvGameCoreDLL/CvUnit.cpp b/CvGameCoreDLL/CvUnit.cpp index b8c8af0f9..469cf1b22 100644 --- a/CvGameCoreDLL/CvUnit.cpp +++ b/CvGameCoreDLL/CvUnit.cpp @@ -612,10 +612,7 @@ void CvUnit::kill(bool bDelay, PlayerTypes ePlayer) { for (int iI = 0; iI < MAX_PLAYERS; iI++) { - // Absinthe: only if the player is also alive (no message in autoplay) - //if (GET_PLAYER((PlayerTypes)iI).isAlive()) - if ((GET_PLAYER((PlayerTypes)iI).isAlive()) && - (GC.getGameINLINE().getGameTurn() >= startingTurn[GC.getGameINLINE().getActivePlayer()])) + if (GET_PLAYER((PlayerTypes)iI).isAlive()) { szBuffer = gDLL->getText("TXT_KEY_MISC_GENERAL_KILLED", getNameKey()); gDLL->getInterfaceIFace()->addHumanMessage( diff --git a/CvGameCoreDLL/CyGlobalContext.cpp b/CvGameCoreDLL/CyGlobalContext.cpp index 89e72a43e..b4d247261 100644 --- a/CvGameCoreDLL/CyGlobalContext.cpp +++ b/CvGameCoreDLL/CyGlobalContext.cpp @@ -560,15 +560,6 @@ CvTurnTimerInfo *CyGlobalContext::getTurnTimerInfo(int i) const } // 3Miro: Balancing functions -void CyGlobalContext::setStartingTurn(int iCiv, int iVal) -{ - /*if ( startingTurn == NULL ){ - startingTurn = new int[NUM_ALL_PLAYERS_B]; - for ( int i=0; i &x) x // 3Miro balancing stuff, expose to Python - .def("setStartingTurn", &CyGlobalContext::setStartingTurn, "void (int iCiv, int iVal)") // 3Miro - .def("getStartingTurn", &CyGlobalContext::getStartingTurn, "int (int iCiv )") // 3Miro - .def("setGrowthModifiersAI", &CyGlobalContext::setGrowthModifiersAI, "void ( int iCiv, int iPop, int iCult, int iGP, int iWorker, int iHealth, int iInitPop )") // 3Miro .def("setProductionModifiersAI", &CyGlobalContext::setProductionModifiersAI, @@ -40,7 +37,6 @@ void CyGlobalContextPythonInterface5(python::class_ &x) .def("setInitialBuilding", &CyGlobalContext::setInitialBuilding, "void ( int iCiv, int iBuilding, bool w )") // 3Miro - .def("setStartingTurn", &CyGlobalContext::setStartingTurn, "void (int iCiv, int iVal)") // 3Miro .def("setCityClusterAI", &CyGlobalContext::setCityClusterAI, "void (int iCiv, int iTop, int iBottom, int iMinus )") // 3Miro .def("setCityWarDistanceAI", &CyGlobalContext::setCityWarDistanceAI, "void (int iCiv, int iVal)") // 3Miro @@ -147,9 +143,6 @@ void CyGlobalContextPythonInterface5(python::class_ &x) // set AI building prefs .def("setBuildingPref", &CyGlobalContext::setBuildingPref, "void ( int iCiv, int iBuilding, int iPref )") // 3Miro - // 3Miro: set Autorun Hack - .def("setAutorunHack", &CyGlobalContext::setAutorunHack, "void ( int iUnit, int iX, int iY )") // 3Miro - // 3Miro: set Building + Civic combo .def("setBuildingCivicCommerseCombo1", &CyGlobalContext::setBuildingCivicCommerseCombo1, "void ( int iCode )") // 3Miro diff --git a/CvGameCoreDLL/CyPlayer.cpp b/CvGameCoreDLL/CyPlayer.cpp index c2d0a744c..0c043a88d 100644 --- a/CvGameCoreDLL/CyPlayer.cpp +++ b/CvGameCoreDLL/CyPlayer.cpp @@ -2623,3 +2623,29 @@ int CyPlayer::getDomainFreeExperience(int iDomainType) { return m_pPlayer ? m_pPlayer->getDomainFreeExperience((DomainTypes)iDomainType) : -1; } + +int CyPlayer::getInitialBirthTurn() +{ + return m_pPlayer ? m_pPlayer->getInitialBirthTurn() : -1; +} + +void CyPlayer::setInitialBirthTurn(int iNewValue) +{ + if (m_pPlayer) + { + m_pPlayer->setInitialBirthTurn(iNewValue); + } +} + +int CyPlayer::getLastBirthTurn() +{ + return m_pPlayer ? m_pPlayer->getLastBirthTurn() : -1; +} + +void CyPlayer::setLastBirthTurn(int iNewValue) +{ + if (m_pPlayer) + { + m_pPlayer->setLastBirthTurn(iNewValue); + } +} diff --git a/CvGameCoreDLL/CyPlayer.h b/CvGameCoreDLL/CyPlayer.h index 0824f9369..4d16f3262 100644 --- a/CvGameCoreDLL/CyPlayer.h +++ b/CvGameCoreDLL/CyPlayer.h @@ -633,6 +633,10 @@ class CyPlayer //Leoreth int getDomainFreeExperience(int iDomainType); + int getInitialBirthTurn(); + void setInitialBirthTurn(int iNewValue); + int getLastBirthTurn(); + void setLastBirthTurn(int iNewValue); private: CvPlayer *m_pPlayer; diff --git a/CvGameCoreDLL/CyPlayerInterface2.cpp b/CvGameCoreDLL/CyPlayerInterface2.cpp index 07c7067eb..8a56d5939 100644 --- a/CvGameCoreDLL/CyPlayerInterface2.cpp +++ b/CvGameCoreDLL/CyPlayerInterface2.cpp @@ -172,5 +172,11 @@ void CyPlayerPythonInterface2(python::class_ &x) .def("setLeader", &CyPlayer::setLeader, "void (int i)") //Rhye .def("getLeader", &CyPlayer::getLeader, "int /*LeaderHeadTypes*/ ()") //Rhye - .def("isExisting", &CyPlayer::isExisting, "bool ()"); + .def("isExisting", &CyPlayer::isExisting, "bool ()") + + //Leoreth + .def("getInitialBirthTurn", &CyPlayer::getInitialBirthTurn, "int ()") + .def("setInitialBirthTurn", &CyPlayer::setInitialBirthTurn, "void (int iNewValue)") + .def("getLastBirthTurn", &CyPlayer::getLastBirthTurn, "int ()") + .def("setLastBirthTurn", &CyPlayer::setLastBirthTurn, "void (int iNewValue)"); }