You click "End Turn" and then it (randomly, sooner or later) crashes in between turns(?). That's what I was assuming. I see the GitHub repo. Those are large commits that probably won't allow reverting to some earlier version where the error didn't yet exist. If Visual Studio on Windows is available and working, then I'll go back to my original suggestion: Reproducing the error with an Assert build; if that yields nothing, attaching the debugger.
Same disappointing result as when I prodded ... was it <Nexus>? ... to attach a debugger. Unless there's some DLL function on the call stack (Alt+7), but I doubt it. Probably this only tells us that the crash happens in the EXE. That might indicate that it's an artwork issue. If you remove the Art folder, does the crash still occur? I was going to try that myself, but it seems that I can't reproduce the issue. I got your mod from GitHub (I guess that should make no difference), the savegame from this thread. One issue I did encounter is that my user profile was automatically unloaded. Probably because of the Route Bombing player option. I think the PLAYEROPTION_MODDER elements in Civ4PlayerOptionInfos.xml were supposed to prevent such issues; though I don't know how exactly they're supposed to be used. Anyway, since I'm not even getting the crash, that's apparently not the real problem. I've ended my turn 5 times in Globe view, then reloaded, ended it 6 times in non-Globe view, reloaded again, enabled audio, and ended the turn 5 more times in non-Globe view. At some point I thought the game was hanging, but it was just a long AI turn, I guess. No serious problems. A "Six Day War" popup shows up after a few turns. Tried it only in windowed mode. I guess a number of local settings could, in theory, make a difference.
Well, after this issue will (hopefully) resolve itself somehow, perhaps the Assert and Debug builds can still prove useful in the future.
VOID addCheckBoxGFC (
STRING szName, STRING szTexture, STRING szHiliteTexture,
INT iX, INT iY, INT iWidth, INT iHeight,
WidgetType eWidgetType, INT iData1, INT iData2,
ButtonStyle eStyle)
And xLoop gets updated as xLoop += self.DX_RELIGION. The constants in question:
Python:
self.DX_RELIGION = 98
self.BUTTON_SIZE = 48
So changing the BUTTON_SIZE constant (near the top of the file) will not affect xLoop, i.e. the dynamic element of the positioning. But also decreasing DX_RELIGION should do the job. Since your mod is apparently not based on the BUG mod (that would bring its own religion screen), you can experiment with Python changes at runtime; the game detects when a file is changed on disk and then automatically reloads the Python module. (BUG breaks that feature.) Maybe best to close the religion screen in between code changes.
For wrapping around, iY (not just iX) would need to depend on the number of loop iterations. Currently, it's only based on constants. Maybe a job for AI. Perplexity.ai gives me this:
SpoilerAI convo :
Could you make these button icons wrap around?
Python:
# Religion buttons at the top
xLoop = self.X_RELIGION_START
for i in range(gc.getNumReligionInfos()):
szButtonName = self.getReligionButtonName(i)
if gc.getGame().getReligionGameTurnFounded(i) >= 0:
screen.addCheckBoxGFC(szButtonName, gc.getReligionInfo(i).getButton(), ArtFileMgr.getInterfaceArtInfo("BUTTON_HILITE_SQUARE").getPath(), self.X_RELIGION_AREA + xLoop - self.BUTTON_SIZE/2, self.Y_RELIGION_AREA + self.Y_RELIGION - self.BUTTON_SIZE/2, self.BUTTON_SIZE, self.BUTTON_SIZE, WidgetTypes.WIDGET_GENERAL, -1, -1, ButtonStyles.BUTTON_STYLE_LABEL)
xLoop += self.DX_RELIGION
It should be a matter of choosing iX = self.X_RELIGION_AREA + xLoop - self.BUTTON_SIZE/2
and iY = self.Y_RELIGION_AREA + self.Y_RELIGION - self.BUTTON_SIZE/2
differently – increasing iY to second (or third etc.) row when iX would exceed some vertical right edge boundary.
This looks legit to me, but I haven't tested it, and I'd try to use it as a guide rather than copy-paste it. Calculating iY twice is clearly unnecessary. Hm, searching for all uses of DX_RELIGION, I see that there are several other loops that place labels, which probably need to be aligned with the one I gave to the chat bot. And the iX, iY formulas are repeated in an "else" branch that places nonselectable images for religions not yet founded. So getting wrap-around to work will probably require changes in a number of places (or a good amount of code restructuring). Whereas changes to DX_RELIGION and other constants should only need to be changed in a single place (toward the top, where they're defined).
Yeah I tried what the AI suggested and it made all UI in-game disappear (also skipped all the intro cutscenes on startup). And yes I'm just using BTS without any UI mods.
Editing self.BUTTON_SIZE to 40, self.X_RELIGION_START to 100, and self.DX_RELIGION to 50 had the following effect:
Very close to what I want, just have all the text piled up now (I still have to make the unavailable icons). Thanks for all the help so far! Python isn't my expertise.
The first assertion does look rather innocent. Good to hear you've managed to resolve that one. For the other one, I guess this should be the context (copying from the BtS source code):
I guess it means that the unit class in Civ4CivilizationInfos.xml isn't consistent with the one in Civ4UnitInfos.xml, like in this post. (Though I was getting a failed assertion already when loading XML in that case.) Well, perhaps that's what you've already checked. If you attach the debugger again, you can use the Debug button on the "Assert Failed" popup and hover over eUnitClass and eUnit to see which ones are causing the problem. You'll only get numeric IDs that way, which correspond to the position in XML (the count starting at 0, e.g. for UNITCLASS_LION in Civ4UnitInfos.xml; edit: UNIT_LION, I meant). Or you could edit and recompile the source code for more info, e.g. CvUnitClassInfo& kInfoDbg = GC.getUnitClassInfo(eUnitClass);
And then hovering over kInfoDbg, expanding CvInfoBase and hovering over m_szType for the type name of the unit class.
From the code I copied, it's not apparent that this problem will cause a crash. Maybe it's not the problem that you're trying to solve.
Edit: Hadn't seen the latest post. Those two look more likely to crash - and also to crash only sometimes. Again, attaching the debugger will provide more info. Or perhaps looking at the indicated line of code will already make things clearer. I guess the first one is this (but using your mod's source code would be more reliable):
Spoiler:
C++:
bool CvPlot::isTradeNetworkConnected(const CvPlot* pPlot, TeamTypes eTeam) const
{
FAssertMsg(eTeam != NO_TEAM, "eTeam is not assigned a valid value");
Would be important to know the call stack for this. Some function is calling isTradeNetworkConnected with eTeam=NO_TEAM, and it shouldn't do that. The debugger shows the call stack. Same for the second one:
Spoiler:
C++:
bool CvPlot::isRevealed(TeamTypes eTeam, bool bDebug) const
{
FAssertMsg(eTeam >= 0, "eTeam is expected to be non-negative (invalid Index)");
Well, I hope that it really does work for you as well (when revealing tiles at least).
It seems that this fragment of Platy's is doing the job:
Spoiler:
Python:
if pPlayerX.isHuman() and not CyGame().GetWorldBuilderMode():
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
popupInfo.setData1(iFeature)
popupInfo.setData3(3)
popupInfo.setText(u"showWonderMovie")
popupInfo.addPopup(iPlayerX)
I assume that he used the BtS code in obBuildingBuilt as his starting point. This should result in a call to
in CvScreensInterface.py, and CvWonderMovieScreen also is available to us – and has been modified by Platy to accommodate his tag type naming convention for his natural wonder movies. Which is to say: Modders should have a lot of control over wonder movies.
The wonder status is, I think, just something that onBuildingBuilt checks before showing a movie. But it's just Python code, an exception could be added e.g. for specific building types. And having a cost won't help because onBuildingBuilt only gets called when a city finishes constructing a building. I don't think setNumRealBuilding triggers this event – even if the building has a cost. However, if you can determine where NaturalWonders.py adds the city buildings, you could just move the wonder screen launch code to that place. I wouldn't even consider that a workaround. And I don't think the building needs to have any particular properties for this to work. placeWonderBuilding sounded like the place where the buildings get added, but when I tried it this afternoon, a print statement I put there did not seem to get reached. Maybe I just didn't test it carefully enough.
So I tried doing the above but failed so far.
My goal is to play wonder movie both when the Natural Wonder is discovered and also when its wonder building is placed in a city.
Here is how far I got in the code:
Python:
def placeWonderBuilding(self, pCity):
for i in xrange(21):
pPlot = pCity.getCityIndexPlot(i)
iFeature = pPlot.getFeatureType()
if iFeature == -1:
continue
sType = gc.getFeatureInfo(iFeature).getType()
if sType.find("FEATURE_PLATY_") == -1:
continue
sNature = sType[sType.find("_PLATY_") + 7:]
sBuildingType = "BUILDING_" + sNature
iBuilding = gc.getInfoTypeForString(sBuildingType)
if iBuilding == -1:
continue
if self.checkWonderBuilt(iBuilding):
continue
# Place the wonder in the city
pCity.setNumRealBuilding(iBuilding, 1)
# Trigger the wonder movie popup
popupInfo = CyPopupInfo()
popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
popupInfo.setData1(iBuilding)
popupInfo.setData2(pCity.getID())
popupInfo.setData3(0)
popupInfo.setText(u"showWonderMovie")
popupInfo.addPopup(pCity.getOwner())
return
@<Nexus>: My (quick) impression was that placeWonderBuilding is not the function that (usually) places the wonder. Can you confirm through print statements that the function gets called? If not, I guess the other setNumRealBuilding calls in Platy's code would need to be checked.
@Darkator: That M41 looks fine. At least for the one civ shown on the right. Maybe multiple civs use it (checking my local copy: apparently not). Is that at the position that the debugger indicates?
@Darkator: That M41 looks fine. At least for the one civ shown on the right. Maybe multiple civs use it (checking my local copy: apparently not). Is that at the position that the debugger indicates?
Me too, well, counting just the unit classes. So eUnit is of class UNITCLASS_CW1LIGHT_TANK and, by your count, of type M41, but the unit's owner is not supposed to have such a CW1-class unit ...
You could add UnitTypes eUnitDbg = GC.getCivilizationInfo(getCivilizationType()).getCivilizationUnits(eUnitClass); (and recompile) to be able to see in the debugger which unit ID the owner is actually supposed to have.
But maybe the problem isn't even in XML. If it were, then I'd really expect an assertion to fail already during XML loading. Would be interesting to see where the call to canTrain comes from (Call Stack window). Maybe some mod code is involved. Perhaps the civ in question is not America, but the code somehow still passes the M41 unit ID to the canTrain function. That actually happens easily by just looping through all unit IDs. (The proper way is to loop through unit class IDs and to convert those to unit IDs depending on the civ involved.)
@<Nexus>: My (quick) impression was that placeWonderBuilding is not the function that (usually) places the wonder. Can you confirm through print statements that the function gets called? If not, I guess the other setNumRealBuilding calls in Platy's code would need to be checked.
the game tells me that it should be a normal unit, but the problem is that I want a unit unique to this civilization
I am sending the source code of my CV game core dll
@<Nexus>: That addMessage uses variables iPlayerX, FeatureInfo and pPlot. Perhaps those aren't in place where you've copy-pasted it? You do have Python error popups enabled or check PythonErr.log? Because, otherwise, "ruining" placeWonderBuilding could break the whole module and you might not notice. I'd just put a print statement before the popup code and perhaps after, too, to make sure that your code is reached. Here's how CvWonderMovieScreen.py processes the natural wonders:
MOVIE_SCREEN_WONDER is indeed 0, so I guess Data3=0 and a building ID as Data1 should work. But is the movie stored at the building too in XML? Well, what happens in CvWonderMovieScreen.py – if anything – also can be traced with print statements.
@Darkator: But perhaps the civ in question is not one that should have an M41 (but a regaular UNIT_CW1LIGHT_TANK)? Again, the Call Stack would be informative. And the player ID should be under "Locals", "+this", "m_eID". I could imagine that the reinforcement Python code has given a civ other than America an M41 and that the canTrain check is happening as part of a can-upgrade check. I don't think the DLL changes are the problem; they seem to have little to do with unit production.
But perhaps the civ in question is not one that should have an M41 (but a regaular UNIT_CW1LIGHT_TANK)? Again, the Call Stack would be informative. And the player ID should be under "Locals", "+this", "m_eID". I could imagine that the reinforcement Python code has given a civ other than America an M41 and that the canTrain check is happening as part of a can-upgrade check. I don't think the DLL changes are the problem; they seem to have little to do with unit production.
@<Nexus>: That addMessage uses variables iPlayerX, FeatureInfo and pPlot. Perhaps those aren't in place where you've copy-pasted it? You do have Python error popups enabled or check PythonErr.log?
So Data1 needs to be a feature ID and Data3 needs to be 3. I guess you're aiming at this bit of (original) code instead: elif self.iMovieType == MOVIE_SCREEN_WONDER: self.szMovieFile = gc.getBuildingInfo(iMovieItem).getMovie()MOVIE_SCREEN_WONDER is indeed 0, so I guess Data3=0 and a building ID as Data1 should work. But is the movie stored at the building too in XML? Well, what happens in CvWonderMovieScreen.py – if anything – also can be traced with print statements.
Hello all,
.
I have created art files for the leaderheads using historical still-pictures. These load up for me just fine.
.
I place the Leaderheads folder in Assets > Art > [paste entire leaderheads folder], and the art defines file in xml > art > [paste here] ... but when I send this file to my friend who I play against online and he pasted them in the same folders, the still-picture leaderheads do not show [the vanilla game leaderheads show]. Any idea why this occurs?
.
Edit: I even sent him the duplicate mod I'm using with identical folders as I'm using and it doesn't load the new leaderhead art ... any guesses as to why?
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.