Mod-Modders Guide to Fall Further

I have got another problem with my code "recycling" ;)

I try to import DenyPromotions promotions to Orbis (want to use it to block fort commanders from being able to get mobility, which is useless for them)

I have some problems with SDK, but the main problems is in CIV4UnitSchema.xml
I have added to the unit part of the file:
Code:
		<element type="DenyPromotions" minOccurs="0"/>
and following to promotion part (same way it is in FF file - tried placing it in unit part as well)
Code:
	<ElementType name="DenyPromotions" content="eltOnly">
		<element type="Promotion" minOccurs="0"/>
	</ElementType>
I get "failed to load CIV4UnitClassInfos.xml". Not the normal "unexpected field", fails to load at all.
Any idea what am I doing wrong? Is there any particular order it should follow? Or any other field that is required for it to work properly?
My knowledge of the schema files is limited, but so far my "cut and paste in the proper order" did work
 
Code:
	<ElementType name="DenyPromotions" content="eltOnly">
		<element type="Promotion" minOccurs="0"/>
	</ElementType>
I get "failed to load CIV4UnitClassInfos.xml". Not the normal "unexpected field", fails to load at all.
Any idea what am I doing wrong? Is there any particular order it should follow? Or any other field that is required for it to work properly?
My knowledge of the schema files is limited, but so far my "cut and paste in the proper order" did work

In this section of the schema, you tell it that "DenyPromotions" contains zero or more "Promotion" elements. If I remember correctly that element doesn't exist in base FfH, but is used for Deny/Allow/Exclude/Replace promotions in FF.

You'll need...

Code:
	<ElementType name="Promotion" content="textOnly"/>

...somewhere in it - probably best to put it right after the ElementType definition for Promotion.

"content=eltonly" states that the element contains only other elements (in this case a list of Promotion elements). "content=textOnly" states that the "Promotion" element contains only text - in this case, the name of a promotion ("PROMOTION_COMBAT1" etc).
 
It should be. I've used it in def doHell to decide whether Obsidian Planes should turn to Scrub or Flood Plains, but haven't tested it much.

If you left the parentheses off like you did there it wouldn't work of course.
 
Should be quite possible to use it from any python file if already used in one somewhere. Are you certain that the tile you were attempting to cast in was a Riverside tile? (and why would you mess with the prereq at all, sounds like you are trying to make it act different if you happen to be on a riverside)


Wouldn't you have to dig out a lot of land in addition to removing the grass to make a plains become a floodplains? I thought the main point was that it was sub-water level, so when water was high it covered the whole area or something.
 
Should be quite possible to use it from any python file if already used in one somewhere. Are you certain that the tile you were attempting to cast in was a Riverside tile? (and why would you mess with the prereq at all, sounds like you are trying to make it act different if you happen to be on a riverside)

What do you mean prereq?

Wouldn't you have to dig out a lot of land in addition to removing the grass to make a plains become a floodplains? I thought the main point was that it was sub-water level, so when water was high it covered the whole area or something.

Actually not so much. Quite a few rivers flood their banks, but the vegetation along the river banks tend to slow the water's spread enough that the flood might as well not have happened. Removing the vegetation along flood-prone rivers can drastically extend the range of the floods... Caused alot of problems in some areas of Southern California especially until the residents decided it wasn't worth the floods... the land is now light forest, and used as flood control. It's also the exact thing causing so many problems along the southern Mississippi... Concrete is worse than bare ground at slowing the flow of water.

I'm not going to make ALL desert rivers floodplains, although that's the way Firaxis went. Rather, I'm thinking a 10-20% chance. My code is in defSpellScorch, and is run after plains become desert... Same basic check worked with making forests scrub, but in this case it simply disables Scorch.

Code:
if pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_DESERT'):
	if pPlot.isRiverSide():
		pPlot.setFeatureType(gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS')
 
I assumed you were modifying a pythonprereq type of field if it was disabling your ability to even cast the spell. Anything you place in the pythonresult should have absolutely no bearing on ability to cast the spell one way or another. It can just make it have no effect at best.

Cool note on the flooding though. I just assumed the vegetation helped to prevent erosion and thus kept the ground naturally higher.
 
I think it's better to use isRiver() instead of isRiverSide(), because isRiverSide returns False for one of the plots at the outside of a river bend. And doesn't setFeatureType need two parameters?

Yeah, I'd actually fixed that after posting. I'll try isRiver().... I have no idea why it's disabling scorch when I'm not touching the req, but it is. :wallbash:
 
Are other python spells working? It could be that you made a syntax error somewhere that is stopping that file from loading.
 
In this section of the schema, you tell it that "DenyPromotions" contains zero or more "Promotion" elements. If I remember correctly that element doesn't exist in base FfH, but is used for Deny/Allow/Exclude/Replace promotions in FF.

You'll need...

Code:
	<ElementType name="Promotion" content="textOnly"/>
Thanks !!! Worked great and I was able to import a lot more promotion fields thanks to it :)

Unfortunatelly I have discovered another problem - PromotionReplacedBy tag does not work as advertised. I checked in both my imported code and in FF. I might have missed something, but it seems that it only displays a tooltip which promotion will remove it, but without PromotionOverwrites on the other promotion it does not really work.
Not a big deal (PromotionOverwrites is a wonder :) ), just wanted to confirm if it is really so.

Also, it is already next weekend ;) , so I will allow myself to ask again for a code help for blocking palaces of the conquered/tolerated civs... I would like that palace of the main civ be buildable in every city and the other ones simply blocked, just as heroes are.

Also, any idea why the code below cuases display problems if used without if (!bTestVisible) ?

Code:
bool CvCity::canConstruct(BuildingTypes eBuilding, bool bContinue, bool bTestVisible, bool bIgnoreCost) const
{
	BuildingTypes ePrereqBuilding;

    if (isSettlement())
    {
	if (!bTestVisible)
	{
		if (isWorldWonderClass((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())))
		{
			return false;
		}
		else if (isTeamWonderClass((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())))
		{
			return false;
		}
		else if (isNationalWonderClass((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())))
		{
			return false;
		}
	}
    }
 
Hrm, I remember the ReplacedBy bugging me once before, I guess I didn't sit down and take the time to fix it up at that moment and have lost the note to go back to it. Main reason that both of those tags (replacedBy and Overwrites) exist were so that we could avoid some mass clutter on a few promotions, and ensure documentation existed on others. But our OverrideHelpText tag came later to fill the gap better. Still nice to have them both working properly though.


What kind of display problems are you getting? And there ought to be a isLimitedWonderClass() check to do all three of those for you.

Anyway, if bTestVisible == true, then it is seeing if it should display the icon or not, but doesn't care if you can actually build it or not (ignores some fields). if bTestVisible == false, then it is actually checking if you can build the item legally (all fields should be checked)
 
I get the attached error every time I try to open settlement. With if (!bTestVisible) it works, but I do not want wonders to be displayed (or buildable) at all in settlements.
And there ought to be a isLimitedWonderClass() check to do all three of those for you.
Thanks, the less code, the better!
 

Attachments

  • bug.jpg
    bug.jpg
    22.5 KB · Views: 80
Hey guys. I'm trying to nail down the cause of some OOS issues in Fall Flat that seem to be occuring when some players Random Number Generator gets shunted, causing that player's game to go OOS when the barbs move according to the RNG...(Which normally would be less of a problem if players could connect to a game in progress without causing yet another OOS...) and forcing us all to reload the mod then restart the game.

Since I'm pretty sure the problem is with the random numbers generated through Python, I'm probabaly about to start asking you guys a whole bunch of "What does this code actually DO" questions. Like for example...
What does this do? I'd assume it gets the active player unless the game is MP.
Code:
	def doChanceAwakenedSpawn(self, iPlayer):
		if iPlayer == -1:
			pPlayer = gc.getPlayer(gc.getGame().getActivePlayer())
		else:
			pPlayer = gc.getPlayer(iPlayer)

Of course, I could be wrong about the whole cause of the OOS.
 
If you want to find it instantly, turn on the MP gameoption for logging random numbers, and the look in your logs folder (shortcut to it is in the BtS folder) for the RandomLogger - Player # - Cycle #.log. A new cycle starts every 50 turns to keep the file sizes small.

Just get the last cycle recorded from each player after an OOS happens and WinMerge them, it'll tell you precisely which random started the OOS (as long as your text strings for each new random you made are different that is).


For the function you quoted, it is called from 2 places, one of them is CvMainInterface, which is for display only, so that is meant for the active player and thus doesn't bother specifying a certain player, instead tossing in a -1 value. Not sure why we do it this way, could fairly easily just pass in the iPlayer value. The other place it is called from is the routine to actually spawn awakened for you, in that case it is actually DOING something, so it must call to a specific player, and thus it passes in a player number.
 
Another question spawned by promotionexcludes tag.

If spell adds promotion that is excluded/denied, the spell can be cast but promotion is not added, so the spell does nothing. I think it should block casting of the spell.
I guess the block has to be added to bool CvUnit::canCast, in this part:
Code:
    if (GC.getSpellInfo(eSpell).getAddPromotionType1() != NO_PROMOTION)
    {
        if (canAddPromotion(spell))
        {
            return true;
        }
    }
But unfortunatelly, I have no idea how to do it (if it can be done at all). Any advice? It can be usefull in FF, too :mischief:
Of course, it can be done in python, but it might be better to do it here.
 
Back
Top Bottom