1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

Bug Thread

Discussion in 'Civ4 - Final Frontier Plus' started by TC01, May 26, 2010.

  1. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    Wouldn't this be a problem with wrapping maps too? Or is there some logic in the code that checks for the wrap and changes the plots accordingly?
     
  2. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    It might depend on how it is doing it. At least some places deal with the wrap, so you'd have to check the specific method it uses to be sure.
     
  3. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    I have worked my way through the assert failures. Some of them point to real problems, some don't. Any that pointed to real problems got fixed.

    Theoretically, the first issue (TRAIT_*) may be a minor problem, but I didn't feel like tracking down which XML file was being defaulted to a BtS (or Warlords, or Vanilla)
    XML file that was using them. If my secondary traits are ever added back in, it will
    no longer be an issue since they have all the same names as the regular traits.

    Anyhow, this is what I found:
    Code:
    			ON LOAD:
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_AGGRESSIVE not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_CHARISMATIC not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_CREATIVE not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_FINANCIAL not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_IMPERIALIST not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_INDUSTRIOUS not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_ORGANIZED not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_PHILOSOPHICAL not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_PROTECTIVE not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    			----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvglobals.cpp
    			Line:  3493
    			Expression:  strcmp(szType, "NONE")==0 || strcmp(szType, "")==0
    			Message:  info type TRAIT_SPIRITUAL not found, Current XML file is: xml\GameInfo/CIV4EspionageMissionInfo.xml
    
    
    
    None of the above are what they seem. The TRAIT_* text appears nowhere in
    CIV4EspionageMissionInfo.xml, which is a file that is not present in FFP
    (with BUG or not) and is therefore defaulting to the one from BtS.
    These are all reported in xml.log a the very end so it is claiming
    this as the XML file just because it was the last one that is read
    and these come after that (presumably in some readpass2 or 3 type
    function for resolving the interfile dependencies).
    
    Since these TRAIT_* strings don't occur anywhere in FFP's XML files
    other than some commented out sections of CIV4BuildingInfos.xml they
    must be in an XML file that is being defaulted to the BtS (or earlier)
    version.
    
    ----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvplayer.cpp
    			Line:  11669
    			Expression:  eIndex < GC.getNumCivicOptionInfos()
    			Message:  eIndex is expected to be within maximum bounds (invalid Index)
    
    This is a BUG bug.
    			
    In autologEventManager.py there are hardcoded loops that go over 5 
    civicoption types when FFP only has 4 civicoption categories. This is
    used to store civic options for each civ and check to see if they have
    changed and such.
    
    Relevant code is all over the place, about everywhere the self.CIVCivics
    variable is used including its initialization.
    
    Instead of using "5" it needs to use the actual number as returned by
    gc.getNumCivicOptionInfos() in a bunch of places.
    
    ----------------------------------------------------------
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvteam.cpp
    			Line:  3451
    			Expression:  eIndex >= 0
    			Message:  eIndex is expected to be non-negative (invalid Index)
    
    This assert is in CvTeam::isHasMet.
    			
    This is probably an FF bug. Or two+, actually. In FinalFrontierEvents.py (and
    CvFinalFrontierEvents.py in FFP and FF) in the doAIWarChance function it
    is looping over all possible teams via
    "for iLoopTeam in range(gc.getMAX_CIV_TEAMS()):"
    but it never checks to see if the team number it is checking is alive or
    has ever been alive. It gets the team leader for each, so it should check
    that player to see if they exist and are alive before it uses the team ID.
    
    A similar set of loops is used in CvWBDesc.py. There are no checks of any
    sort run to see if the returned number is a valid team. These not only
    use the isHasMet function, but various others like isVassal and
    getEspionagePointsAgainstTeam.
    
    BUG's CvExoticForeignAdvisor does this in one location too, in drawInfoImproved
    it is looping over all possible players without checking them to see if they
    are valid before getting the TeamInfo and calling isHasMet.
    
    Fixes have been put in place for all of them that I found.
    
    Since this was happening on load, I think this would have been the CvWBDesc.py
    issue, but if that is the case I don't know why the functions other than isHasMet
    didn't fire off their asserts too.
    
    ----------------------------------------------------------
    
    			ON CLICKING NEXT TURN:
    
    			Assert Failed
    
    			File:  f:\civilization 4 mods\sdk stuff\dll 1 bts\1.651 debug dll\cvgamecoredll\cvcity.cpp
    			Line:  1096
    			Expression:  iCount == getBaseYieldRate((YieldTypes)iI)
    			Message:  
    
    This is spurious. It is in a chunk of code that is only compiled for a debug
    build which is apparently recalculating the the city's total base yields
    (as the sum of the output from worked plots, specialists, buildings, trade
    routes, and corporations) and comparing this local calculation to what
    getBaseYieldRate returns. The calculation it does is evidently not including
    everything that FFP does to get its base yields.
     
  4. TC01

    TC01 Deity

    Joined:
    Jun 28, 2009
    Messages:
    2,216
    Location:
    Irregularly Online
    I believe when the failures occur in EspionageMissionInfos, they're really occuring in Python somewhere- that is the last XML file to get loaded, so assert failures that are happening in Python (I think) get attributed to it.

    Thanks for looking into it!
     
  5. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    I looked at the doGravityField code so I can fix the bug in Star Trek, but it appears as if the code doesn't compensate for the map wrap at all! Please correct me if I'm wrong, but I didn't see anything indicating wrap corrections. Does the function to get the plot already compensate for wrapping?
     
  6. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    The function plotINLINE() does adjust the coordinates for wrap to get you the correct plot via the coordRange() function calls. Both of these functions are defined in CvMap.h (not .cpp).
     
  7. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    Good to know. Looks like my cloaking code is a lot more complicated than it needs to be...
     
  8. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,425
    Location:
    Britain
    I've come across an error whilst play testing the B5 mod. When you first start playing and building up your planetary infrastructure the number of hammers remains stable (see pics 1,2 and 3) until the Recycling Center is built (see pic 4) when the production shoots up to a huge figure making it possible to churn out a lot more buildings & ships early on, for some reason the production drops back down to a more normal figure after you have built your 2nd recycling centre.
    Here is the building infos XML for the recycling centre we use in the mod.

    Code:
    		<BuildingInfo>
    			<BuildingClass>BUILDINGCLASS_RECYCLING_CENTER</BuildingClass>
    			<Type>BUILDING_RECYCLING_CENTER</Type>
    			<SpecialBuildingType>NONE</SpecialBuildingType>
    			<Description>TXT_KEY_BUILDING_RECYCLING_CENTER</Description>
    			<Civilopedia>TXT_KEY_BUILDING_RECYCLING_CENTER_PEDIA</Civilopedia>
    			<Strategy>TXT_KEY_BUILDING_RECYCLING_CENTER_STRATEGY</Strategy>
    			<Help/>
    			<Advisor>ADVISOR_GROWTH</Advisor>
    			<ArtDefineTag>ART_DEF_BUILDING_RECYCLING_CENTER</ArtDefineTag>
    			<MovieDefineTag>NONE</MovieDefineTag>
    			<HolyCity>NONE</HolyCity>
    			<ReligionType>NONE</ReligionType>
    			<StateReligion>NONE</StateReligion>
    			<bStateReligion>0</bStateReligion>
    			<PrereqReligion>NONE</PrereqReligion>
    			<PrereqCorporation>NONE</PrereqCorporation>
    			<FoundsCorporation>NONE</FoundsCorporation>
    			<GlobalReligionCommerce>NONE</GlobalReligionCommerce>
    			<GlobalCorporationCommerce>NONE</GlobalCorporationCommerce>
    			<VictoryPrereq>NONE</VictoryPrereq>
    			<FreeStartEra>NONE</FreeStartEra>
    			<MaxStartEra>NONE</MaxStartEra>
    			<ObsoleteTech>NONE</ObsoleteTech>
    			<PrereqTech>TECH_B5_ADVANCED_RECYCLING</PrereqTech>
    			<TechTypes/>
    			<Bonus>NONE</Bonus>
    			<PrereqBonuses/>
    			<ProductionTraits/>
    			<HappinessTraits/>
    			<NoBonus>NONE</NoBonus>
    			<PowerBonus>NONE</PowerBonus>
    			<FreeBonus>NONE</FreeBonus>
    			<iNumFreeBonuses>0</iNumFreeBonuses>
    			<FreeBuilding>NONE</FreeBuilding>
    			<FreePromotion>NONE</FreePromotion>
    			<CivicOption>NONE</CivicOption>
    			<GreatPeopleUnitClass>NONE</GreatPeopleUnitClass>
    			<iGreatPeopleRateChange>0</iGreatPeopleRateChange>
    			<iHurryAngerModifier>0</iHurryAngerModifier>
    			<bBorderObstacle>0</bBorderObstacle>
    			<bTeamShare>0</bTeamShare>
    			<bWater>0</bWater>
    			<bRiver>0</bRiver>
    			<bPower>0</bPower>
    			<bDirtyPower>0</bDirtyPower>
    			<bAreaCleanPower>0</bAreaCleanPower>
    			<DiploVoteType>NONE</DiploVoteType>
    			<bForceTeamVoteEligible>0</bForceTeamVoteEligible>
    			<bCapital>0</bCapital>
    			<bGovernmentCenter>0</bGovernmentCenter>
    			<bGoldenAge>0</bGoldenAge>
    			<bAllowsNukes>0</bAllowsNukes>
    			<bMapCentering>0</bMapCentering>
    			<bNoUnhappiness>0</bNoUnhappiness>
    			<bNoUnhealthyPopulation>0</bNoUnhealthyPopulation>
    			<bBuildingOnlyHealthy>0</bBuildingOnlyHealthy>
    			<bNeverCapture>0</bNeverCapture>
    			<bNukeImmune>0</bNukeImmune>
    			<bPrereqReligion>0</bPrereqReligion>
    			<bCenterInCity>0</bCenterInCity>
    			<iAIWeight>0</iAIWeight>
    			<iCost>40</iCost>
    			<iHurryCostModifier>0</iHurryCostModifier>
    			<iAdvancedStartCost>50</iAdvancedStartCost>
    			<iAdvancedStartCostIncrease>0</iAdvancedStartCostIncrease>
    			<iMinAreaSize>-1</iMinAreaSize>
    			<iConquestProb>50</iConquestProb>
    			<iCitiesPrereq>0</iCitiesPrereq>
    			<iTeamsPrereq>0</iTeamsPrereq>
    			<iLevelPrereq>0</iLevelPrereq>
    			<iMinLatitude>0</iMinLatitude>
    			<iMaxLatitude>90</iMaxLatitude>
    			<iGreatPeopleRateModifier>0</iGreatPeopleRateModifier>
    			<iGreatGeneralRateModifier>0</iGreatGeneralRateModifier>
    			<iDomesticGreatGeneralRateModifier>0</iDomesticGreatGeneralRateModifier>
    			<iGlobalGreatPeopleRateModifier>0</iGlobalGreatPeopleRateModifier>
    			<iAnarchyModifier>0</iAnarchyModifier>
    			<iGoldenAgeModifier>0</iGoldenAgeModifier>
    			<iGlobalHurryModifier>0</iGlobalHurryModifier>
    			<iExperience>0</iExperience>
    			<iGlobalExperience>0</iGlobalExperience>
    			<iFoodKept>0</iFoodKept>
    			<iAirlift>0</iAirlift>
    			<iAirModifier>0</iAirModifier>
    			<iAirUnitCapacity>0</iAirUnitCapacity>
    			<iNukeModifier>0</iNukeModifier>
    			<iNukeExplosionRand>0</iNukeExplosionRand>
    			<iFreeSpecialist>0</iFreeSpecialist>
    			<iAreaFreeSpecialist>0</iAreaFreeSpecialist>
    			<iGlobalFreeSpecialist>0</iGlobalFreeSpecialist>
    			<iMaintenanceModifier>0</iMaintenanceModifier>
    			<iWarWearinessModifier>0</iWarWearinessModifier>
    			<iGlobalWarWearinessModifier>0</iGlobalWarWearinessModifier>
    			<iEnemyWarWearinessModifier>0</iEnemyWarWearinessModifier>
    			<iHealRateChange>0</iHealRateChange>
    			<iHealth>1</iHealth>
    			<iAreaHealth>0</iAreaHealth>
    			<iGlobalHealth>0</iGlobalHealth>
    			<iHappiness>1</iHappiness>
    			<iAreaHappiness>0</iAreaHappiness>
    			<iGlobalHappiness>0</iGlobalHappiness>
    			<iStateReligionHappiness>0</iStateReligionHappiness>
    			<iWorkerSpeedModifier>0</iWorkerSpeedModifier>
    			<iMilitaryProductionModifier>0</iMilitaryProductionModifier>
    			<iSpaceProductionModifier>0</iSpaceProductionModifier>
    			<iGlobalSpaceProductionModifier>0</iGlobalSpaceProductionModifier>
    			<iTradeRoutes>0</iTradeRoutes>
    			<iCoastalTradeRoutes>0</iCoastalTradeRoutes>
    			<iGlobalTradeRoutes>0</iGlobalTradeRoutes>
    			<iTradeRouteModifier>0</iTradeRouteModifier>
    			<iForeignTradeRouteModifier>0</iForeignTradeRouteModifier>
    			<iGlobalPopulationChange>0</iGlobalPopulationChange>
    			<iFreeTechs>0</iFreeTechs>
    			<iDefense>0</iDefense>
    			<iBombardDefense>0</iBombardDefense>
    			<iAllCityDefense>0</iAllCityDefense>
    			<iEspionageDefense>0</iEspionageDefense>
    			<iAsset>2</iAsset>
    			<iPower>0</iPower>
    			<fVisibilityPriority>1.0</fVisibilityPriority>
    			<SeaPlotYieldChanges/>
    			<RiverPlotYieldChanges/>
    			<GlobalSeaPlotYieldChanges/>
    			<YieldChanges>
    				<iYield>1</iYield><!-- Food -->
    				<iYield>1</iYield><!-- Hammers -->
    				<iYield>1</iYield><!-- Credits -->
    			</YieldChanges>
    			<CommerceChanges/>
    			<ObsoleteSafeCommerceChanges/>
    			<CommerceChangeDoubleTimes/>
    			<CommerceModifiers/>
    			<GlobalCommerceModifiers/>
    			<SpecialistExtraCommerces/>
    			<StateReligionCommerces/>
    			<CommerceHappinesses/>
    			<ReligionChanges/>
    			<SpecialistCounts/>
    			<FreeSpecialistCounts/>
    			<CommerceFlexibles/>
    			<CommerceChangeOriginalOwners/>
    			<ConstructSound>AS2D_BUILD_RECYCLING_CENTER</ConstructSound>
    			<BonusHealthChanges/>
    			<BonusHappinessChanges/>
    			<BonusProductionModifiers/>
    			<UnitCombatFreeExperiences/>
    			<DomainFreeExperiences/>
    			<DomainProductionModifiers/>
    			<BuildingHappinessChanges/>
    			<PrereqBuildingClasses/>
    			<BuildingClassNeededs/>
    			<SpecialistYieldChanges/>
    			<BonusYieldModifiers/>
    			<ImprovementFreeSpecialists/>
    			<Flavors>
    				<Flavor>
    					<FlavorType>FLAVOR_GROWTH</FlavorType>
    					<iFlavor>10</iFlavor>
    				</Flavor>
    			</Flavors>
    			<HotKey/>
    			<bAltDown>0</bAltDown>
    			<bShiftDown>0</bShiftDown>
    			<bCtrlDown>0</bCtrlDown>
    			<iHotKeyPriority>0</iHotKeyPriority>
    			<iCostModIncrease>2</iCostModIncrease>
    		</BuildingInfo>
    If you have any ideas as to what may be causing the jump in production i would love to hear them.

    P.S. Although my primary concern was the production/hammers the food production is similarly affected.
     
  9. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    This looks like an issue that was fixed in v1.65 of FFP.

    The issue is that the counters in the CvCity::doTurn() function where it is calculating the base yield levels are not zeroed properly.

    Based on your note in the mod, you are using the v3 version of your DLL. In there you have this:
    Code:
    	CvPlayer& pPlayer = GET_PLAYER(getOwner());
    	int iYield = 0;
    	int iBuildingYield = 0;
    	int iTraitYield = 0;
    	setFoodOverride(0);
    	setProductionOverride(0);
    	setGoldOverride(0);
    	for (int iYieldLoop = 0; iYieldLoop < NUM_YIELD_TYPES; iYieldLoop++)
    	{
    		//Reset iYield to 0
    		iYield = 0;
    
    		//Building yields
    		for (int iBuilding = 0; iBuilding < GC.getNumBuildingInfos(); iBuilding++)
    		{
    			BuildingTypes eBuilding = (BuildingTypes)iBuilding;
    			if (getNumRealBuilding(eBuilding) > 0)
    			{
    				iBuildingYield = GC.getBuildingInfo(eBuilding).getYieldChange(iYieldLoop) * getNumRealBuilding(eBuilding);
    			}
    			iYield += iBuildingYield;
    		}
    
    Note that iBuildingYield is zeroed before the loop for the yield types. It is not zeroed again after that. The first time it finds a building with a yield of the current type it sets iBuildingYield to a non-zero value. That value is then added to the iYield for every single building in the loop after that that does not exist in the city. Once it hits another building that is in the city iBuildingYield is set to whatever the yield for that building is (often, but not always 0). Note that the value is also not zeroed when you loop to the next yield type, so the problem carries over to the later yield types from the earlier ones. Since the order is food, production, then commerce it is typically commerce that gets the worst of it.

    The other parts of this function that do similar things for traits and trade routes don't really have this problem because of the details of the code.

    This section of code was modified in 1.65 so that it doesn't have this problem. For the sake of compatibility you should probably go with the code from 1.65 instead of implementing you own fix. (It was fixed by eliminating the temporary accumulation variable, iBuildingYield. Instead, it just directly adds to iYield.)
     
  10. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,425
    Location:
    Britain
    I guess i must have missed that little update, best i go try and fix it now then lol.

    OK, i've merged in the 1.65 & 1.651 patches and the Mod now runs with no CTD's. However, there is another glitch that has appeared and is similar to one i've had before. In the attached Pic you'll see that the error is an on game start one. Line 170 in my CvFinalFrontierEvents.PY file is
    Code:
    pAlien = CyMap().plot(i)
    . From this I think the answer will be in a map script somewhere. Any suggestions on how to fix this?
     
  11. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    See post 89 in this thread, and surrounding posts...
     
  12. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    I have figures out why it is building two things at one place.

    The thing is that it thinks it is building only outposts. The reason for this is that the ImprovementInfo stores the unit class to make, but the code is taking that number and using it as the unit type. This makes its checks use a semi-random unit. The check does a "if (pUnitInfo.isStarbase() and not pUnitInfo.isOtherStation()):" on this semi-random pUnit, which (not surprisingly) fails. It then falls through to the "else" part which calls canConstructSensorStation. It is never using canConstructStarbase.

    To fix this, I made it get the unit type for the unit class that is appropriate for the civ in question (so it should work even for a starbase UU). The start of the doStationConstructionAI function now looks like this:
    Code:
    	def doStationConstructionAI(self, pUnit, iBuild):
    		"""This function decides what set of other functions to run depending on what the station type is."""
    		pBuildInfo = gc.getBuildInfo(iBuild) # bug fix - was using the non-existent "iStation" instead of iBuild
    		pImprovementInfo = gc.getImprovementInfo(pBuildInfo.getImprovement())
    		[COLOR="DarkRed"][B]pCivilization = gc.getCivilizationInfo(pUnit.getCivilizationType())[/B][/COLOR] # bug fix - part of the fix for the next line
    		[COLOR="DarkRed"][B]pUnitInfo = gc.getUnitInfo(pCivilization.getCivilizationUnits(pImprovementInfo.getUnitClassBuilt()))[/B][/COLOR] # bug fix -  was doing the getUnitInfo on the unit class directly
    		pPlayer = gc.getPlayer(pUnit.getOwner())
    		pTeam = gc.getTeam(pPlayer.getTeam())
    Ran the same turn from the same save as before and now everybody is sending construction ships to two different places. The sensor station locations are still the dead-end-hole-in-a-nebula type places, but the designated starbase builders are headed towards the more usual, and useful, types of places.

    I will be posting some improved choke-point locater code soon. It still won't be great, but it will be better.
     
  13. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,425
    Location:
    Britain
    Thanks for that, updated the mod and going to test it now.
     
  14. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,425
    Location:
    Britain
    Okay, installed the fix, from post #89 to the 1.651 version i am now running but it has thrown up an error on the next line down, see attached pic. I've looked through the posts and can see no mention of this problem. Line 171 is as follows
    Code:
    if pAlien.getFeatureType() == self.iFeatureIDSolarSystem:
    Any suggestions?
     
  15. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    Odd. It ought to be defined on the immediately preceding line.
    Code:
    				pAlien = CyMap().plotByIndex(i)
    				if pAlien.getFeatureType() == self.iFeatureIDSolarSystem:
    The question is, what did you do to the code since v2.0? The code in B5 v2.0, retrieved from the link in your PM, is working (and has the "plotByIndex" fix in it already too, since the lines above were copied from there).
     
  16. PsiCorps

    PsiCorps FF: Babylon 5 mod team

    Joined:
    Dec 30, 2007
    Messages:
    1,425
    Location:
    Britain
    Thanks for the above, i've checked my entries again and it looks like there was an indent where there shouldn't have been, i've corrected it now and hopefully that should be me ready to upload the corrected B5 V2.0

    I'll re test in the morning as it's getting late here.
     
  17. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    I have an updated location finder for the "other" type base, v a new perhaps not quite accurately named (based on actual functionality rather than desired functionality) findBestChokepoint function.

    This is better than the original, but it is still not exactly what I'd call "good".

    Code:
    	def findBestChokepoint(self, iPlayer=-1, bCheckForVisibility=false):
    		"""Returns a tuple of the best chokepoint plot and its plot value."""
    		pBestPlot = -1
    		iBestValue = -1
    		pPlayer = -1
    		iTeam = -1
    		if (iPlayer >= 0):
    			pPlayer = gc.getPlayer(iPlayer)
    			iTeam = pPlayer.getTeam()
    
    		iFeatNebula = gc.getInfoTypeForString('FEATURE_ICE')
    		iFeatAsteroid = gc.getInfoTypeForString('FEATURE_FOREST')
    			
    		iMaxRange = max(CyMap().getGridWidth() / 2, 60)
    		printd("findBestChokepoint    iMaxRange = %d" % (iMaxRange))		
    		for iPlotLoop in range(CyMap().numPlots()):
    			pLoopPlot = CyMap().plotByIndex(iPlotLoop)
    			
    			# If we're supposed to be checking for a player's visibility then only check this plot if it's revealed
    			if (bCheckForVisibility):
    				if (not pLoopPlot.isRevealed(iTeam, false)):
    					continue
    
    			# CP - Check the plot being rated to see if it already belongs to someone else.
    			iPlotOwner = pLoopPlot.getOwner()
    			if ((iPlotOwner != -1) and (iPlotOwner != iPlayer)):
    				continue
    
    			# Don't build anywhere except in empty space & asteroids
    			if (pLoopPlot.getFeatureType() != -1 and pLoopPlot.getFeatureType() != iFeatAsteroid):
    				continue
    
    			iDistanceFromCapital = CyMap().getGridWidth()
    			
    			if (pPlayer.getCapitalCity()):
    				iDistanceFromCapital = CyMap().calculatePathDistance(pPlayer.getCapitalCity().plot(), pLoopPlot)
    			
    			# Don't look too far away (performance, more than anything)
    			if (iDistanceFromCapital > 0 and iDistanceFromCapital < iMaxRange):
    				
    				if iDistanceFromCapital < 4 : # Discourage it from building sensor stations right next to the capital
    					iDistanceValueMod = -9    # it will also get a penalty down below for being close to a star system if it is within 2
    				else : # Highest distance scores in the zone from 1/6 iMaxRange to 2/3 iMaxRange, in this zone iDistanceValueMod will be iMaxRange/6
    					iDistanceValueMod =  ((2 * min( iDistanceFromCapital, iMaxRange/6)) - max( iDistanceFromCapital - (2 * iMaxRange / 3), 0)) / 2
    				
    				iPlotValue = 0
    				iNumNebula = 0
    				iNumAdjacentNebula = 0
    				iNumAsteroid = 0
    				iNumDamaging = 0
    				for iXSearchLoop in range(pLoopPlot.getX()-2, pLoopPlot.getX()+3):
    					for iYSearchLoop in range(pLoopPlot.getY()-2, pLoopPlot.getY()+3):
    						# If the map does not wrap and the plot is not on the map give a small penalty and skip to the next.
    						# Note that if the plot is off the map then all plots in that row and/or column are off too
    						# so it will actually be at least 5 plots that give this penalty.
    						if not CyMap().isPlot(iXSearchLoop, iYSearchLoop):
    							iPlotValue -= 3
    							continue
    							
    						pSearchPlot = CyMap().plot(iXSearchLoop, iYSearchLoop)
    						
    						# Don't search unseen plots in range of the one we're looking at either
    						if (bCheckForVisibility):
    							if (not pSearchPlot.isRevealed(iTeam, false)):
    								continue
    
    						#Build sensor stations near chokepoints -- TC01
    						iFeature = pSearchPlot.getFeatureType()
    						if iFeature == iFeatNebula:
    							iNumNebula += 1
    							if (abs(iXSearchLoop - pLoopPlot.getX()) <= 1) and (abs(iYSearchLoop - pLoopPlot.getY()) <=1):
    								iNumAdjacentNebula += 1
    						elif iFeature == iFeatAsteroid:
    							iNumAsteroid +=1
    						elif (iFeature != -1) and (gc.getFeatureInfo(iFeature).getTurnDamage() > 0): # bug fix - make sure there is a feature before trying to get the info for it, taking advantage of the short-circuit conditional evaluation
    							iNumDamaging += 1
    						elif iFeature == gc.getInfoTypeForString('FEATURE_SOLAR_SYSTEM'):
    							iPlotValue -= 22 # reduce value a lot if near a star system
    						
    						#If other stations are present, no build -- TC01
    						for iUnit in range(pSearchPlot.getNumUnits()):
    							pOtherStarbase = pSearchPlot.getUnit(iUnit)
    							if pOtherStarbase.isStarbase():
    								# iPlotValue = 0
    								iPlotValue -= 99
    								break
    
    				# Some nebula is a good indication of a choke point.
    				# Too much is an indication that we are in a box canyon.
    				# If there are 7 or more adjacent nebula plots, then this is a bad location. Otherwise:
    				# As a guess, make it increase the value for more up to a max value at 13, then decrease fairly rapidly.
    				# Give a score of 0 for 0, increaseing by 3 per nebula up to a score of 39 at 13 through 15,
    				# then decreasing by 5 per nebula over 15.
    				# This is -1 at 23, -6 at 24 and -11 at 25 (which is not a valid location anyway; neither is one
    				# with 23 or 24 since it is unreachable from the capital so the iDistanceFromCapital condition
    				# rules it out before we get here).
    				# Additionally, if there are more than 4 (i.e. 5 or 6) immediately adjacent nebula plots, give a
    				# small penalty of -2.
    				if iNumAdjacentNebula > 6 :
    					iPlotValue -= 99
    				else:
    					iPlotValue += ( 3 * min( iNumNebula, 13)) - ( 5 * max( iNumNebula - 15, 0))
    					if iNumAdjacentNebula > 4 :
    						iPlotValue -= 2 
    
    				# A few asteroids are OK, but they block the visibility (and visibility is the whole point of a sensor station)
    				# With 0 no change, then +5 for 1-3 (which is the max bonus), then -1 for each over 3.
    				# Note that there is still a bonus for being on top of asteroids given later.
    				iPlotValue += ( 5 * min( iNumAsteroid, 1)) - max( iNumAsteroid - 3, 0)
    				
    				# Damaging features are good, but too many is not as good since the area will tend to be avoided and
    				# it is probably between two black holes/supernovas (which is a good chokepoint, but bad for the visibility
    				# aspect since looking at a lot of such plots is rather pointless).
    				# Give +2 per, up to a max of +30 at 15, then -1 per damaging feature over 15
    				iPlotValue += ( 2 * min( iNumDamaging, 15)) - max( iNumDamaging - 15, 0)
    				
    				iPlotValue += iDistanceValueMod
    
    				# Little extra bonus for being in Asteroids (defense)
    				if (pLoopPlot.getFeatureType() == iFeatAsteroid):
    					iPlotValue += 4		#How small should it be?
    
    				# If this plot has the most resources in range from what we've found
    				if (iPlotValue > iBestValue):
    					iBestValue = iPlotValue
    					pBestPlot = pLoopPlot
    				
    				printd("plot %d (%d,%d) value = %d (distance=%d (for %d), NumNebula=%d (adjacent=%d), NumAsteroid=%d, NumDamaging=%d)" % 
    						(CyMap().plotNum(pLoopPlot.getX(), pLoopPlot.getY()), pLoopPlot.getX(), pLoopPlot.getY(), 
    						iPlotValue, iDistanceFromCapital, iDistanceValueMod, iNumNebula, iNumAdjacentNebula, iNumAsteroid, iNumDamaging))
    					
    		printd("* best plot = %d (%d,%d), value = %d" % (CyMap().plotNum(pBestPlot.getX(), pBestPlot.getY()), pBestPlot.getX(), pBestPlot.getY(), iBestValue))
    			
    		return [pBestPlot, iBestValue]
    
    This function seems to max out at a rating of 52 on the map in the Galaxy scenario.

    I suggest changing the threshold in the canConstructSensorStation from 10 up to 45, on the "if (iBestValue > 10)" line.

    I think it might also be a good idea to have the threshold adjusted so that it increases by 1 per sensor station that has already been built. If this is not done, the AIs could ruin their economies on a large map like the Galaxy map by building lots of sensor stations (which are then wiped out by hostile enemies and others since they are strength 0 and the AI doesn't appear to send any ships to protect them).

    The floating threshold version of canConstructSensorStation looks like this:
    Code:
    	def canConstructSensorStation(self, pUnit, iBuild):
    		"""This function checks if the AI can build a sensor station - it uses specific sensor station checks"""
    		bValid = false
    		pBestPlot, iBestValue = self.findBestChokepoint(pUnit.getOwner(), true) # bug fix - was trying to use non-existent iPlayer
    		if (pBestPlot != -1):
    			iX = pBestPlot.getX()
    			iY = pBestPlot.getY()
    
    			pBuildInfo = gc.getBuildInfo(iBuild)
    			pImprovementInfo = gc.getImprovementInfo(pBuildInfo.getImprovement())
    			pCivilization = gc.getCivilizationInfo(pUnit.getCivilizationType())
    			iBuildUnit = pCivilization.getCivilizationUnits(pImprovementInfo.getUnitClassBuilt())
    			pyPlayer = PyPlayer(pUnit.getOwner())
    			apUnitList = pyPlayer.getUnitsOfType(iBuildUnit)
    			iThreshold = 45 + len(apUnitList)
    			printd("canConstructSensorStation: threshold=%d, best=%d" % (iThreshold, iBestValue))
    			if (iBestValue > iThreshold):	# was 10 with old system		#What should be the cutoff for a really good value?
    				bValid = True
    			else:
    				iX = -1
    				iY = -1
    		return (bValid, iX, iY)
     
  18. Maksim

    Maksim Warlord

    Joined:
    Nov 9, 2005
    Messages:
    240
    Hi!

    I'm getting a repeatable crash on hitting "End Turn". Downloaded the latest version of the mod and the patch today. Running a Huge game as the Red Syndicate.

    Save file attached. Python logs don't seem to show anything useful - crash is in civgamecore.dll

    Thanks!
     

    Attached Files:

  19. God-Emperor

    God-Emperor Deity

    Joined:
    Jul 18, 2009
    Messages:
    3,551
    Location:
    Texas
    This is the "black hole too close to the edge of the map" bug. It will be fixed in the next version.

    In your game there is a black hole near the upper edge of the map not too far from the center of that edge. It is 4 spaces from the edge. Sadly, that is 1 space too close. Having a ship enter a grav field that is 2 spaces from the edge of a map causes the search for the associated black hole to try to look at plots that are off the map and therefore do not actually exist, causing it to crash. If you delete that black hole in Worldbuilder, you can continue to play the save.

    The issue only happens for maps that don't wrap, and only if it randomly puts a black hole too close to the edge. It doesn't happen most of the time. It doesn't happen at all if you use maps that wrap (the only one that does is the regular Final Frontier map).
     
  20. Maksim

    Maksim Warlord

    Joined:
    Nov 9, 2005
    Messages:
    240
    Thanks for the explanation - I'll do just that.
     

Share This Page