REQUEST: Simple Plant Forest Mod

DracoDruid

Chieftain
Joined
Feb 8, 2008
Messages
32
Location
Germany
Hey everyone.

I know there might be some Mods that already claim to do what I request,
but several searches haven't uncovered anything close to what I imagine.

I found this mod, where you could build a forest nursery which should improve to a full forest,
if your city is working the tile for IDK 25 rounds or so.
(Who build that btw? Couldn't find the name anywhere in the mod).

Don't know why, but that didn't work in my games
(terraform BTW too, only thing that worked was the Hill up/down thingy)


I am working on some simple modular mods and want to incorp a "Plant Forest" function,
AS SIMPLE AS POSSIBLE.

So, my question: Is it possible?
A simple additional "Build Improvement" Option for the Worker Unit.
No working the tile or what ever, just start building X rounds and after that -
Puff, a Forest.

I bet several of you have tried it, and there must be a reason why it's not done yet.

Maybe some of you can enlighten me on this.

Thanks
 
It sounds like you've already found the Terraforming Modcomp by Avain. This mod is written in Python,and unfortunately Avain hasn't been very active, he has only popped in a couple of times to say he'd fix his popular VD mod, only to disappeared again, so you are unlikely to get help directly from the mod's creator. The reason this hasn't been done is because to do so is complex, particularly to get the AI to actually use the feature. To implement this function correctly would require some DLL modding, and some decent C programming skills.

If you're interested the best thing to do would be to start a thread on this in the Python/SDK forum, and go from there. This component would be something a few modders would be interested in, so you'd likely get some help developing it. This is what I did to learn C++ anyway, just grabbed some source files and used my idea, tried to code it with no knowledge, broke stuff, and asked for help in the Python/SDK forums here. Just be prepared to do alot of google searching, and don't expect things to work right away.
 
Hmm...

Well, I must admit, I don't care for the AI.

I mostly mod for my fun and not for the AI's fun. ;)

The Strange thing is, his Python Code for making/removing a hill is working,
so why won't the same work for planting a forest?

That's so odd.

Anyone took a look into his code?


Oh, and for clearing things out:
I DON'T WANT TO GET HELP FOR THE TERRAFORM MOD,
I WANT TO MOD IT MYSELF.


EDIT:

I just checked it, the Terraforming works too.
I removed the stuff with the Improvement Growing.
Now they work the plot and when they are finished the plot's terrain changes.

Avain, if you read this: GREAT WORK!
 
Sounds like a job for Python. You add an improvement buidable on Grass that when you build it it triggers python to place forest on the same plot. I set one up called Nursery that looks like Forest Preserve, but it can be invisible if you want.
Then

I tried this in CvEventManager and it didn't work.

Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		#pPlot = CyMap().plot(iX, iY)
		iForesteType = CvUtil.findInfoTypeNum(gc.getFeatureInfo, gc.getNumFeatureInfos(),'FEATURE_FOREST')
		iNursery = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_NURSERY')
		iImprovement, iX, iY = argsList
		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))
		if (iImprovement == iNursery):
			pPlot.setFeatureType(gc.getInfoTypeForString( "FEATURE_FOREST" ), 1, 1)

That's the thing I hate about Python, you can't see what got passed into the function and what didn't. Its just "argslist".
 

Attachments

That's the thing I hate about Python, you can't see what got passed into the function and what didn't. Its just "argslist".

That's not Python, it's the way the C++ sends the arguments to the Python.

But it you look at the functions in the original BtS files you can see that they unpack the argsList into more descriptively named variables:
Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList

Which is still done in the code you posted after it does some other stuff.
 
So what do we do?

Just for comparison, here's the Code from Avain (slightly modified by me):

The Code IS triggered, and the Improvement is removed, BUT the Forest does not spawn!

Might this be because Forests don't spread over improvements?


Take a look at the last line. What is the last number for?
It was 0 in avain's original, but I thought it might be the Terrain_Variety Variable?

Code:
if(iImprovement==gc.getInfoTypeForString('IMPROVEMENT_TREE_NURSERY')):
			pPlot = CyMap().plot(iX, iY)
			CyInterface().addMessage(CyGame().getActivePlayer(),True,25,'New Forest planted','AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/TerrainFeatures/Forest.dds',ColorTypes(8),iX,iY,True,True)
			pPlot.setImprovementType(-1)
			pPlot.setFeatureType(gc.getInfoTypeForString('FEATURE_FOREST'), 1)
 
If it runs the contents of the "if" block and removes the improvement, it ought to set the plot to be forest. The second argument is the specific variety. In the original code you posted the processing for this is all after an if block with a return in it. If you did not have self.__LOG_IMPROVEMENT set to True it would never get to it. You should be doing all of this before that "if" statement.

Also, you may need to wait for an update for the plot to actually see the trees (I can't say that I know what causes an update - end of turn certainly should do it if the plot is visible to you), but the hover help for the tile should say it has forest.

Spreading is irrelevant - this is not spread, it is manual placement. It should even work for placing forest on plots that can't normally have forest, like a desert plot.
 
IT WORKS!!!!!

AND YOU WON'T BELIEVE IT!!!


The reason why the Forest never spawned, was because :wallbash: it :wallbash: was :wallbash: chopped :wallbash: down :wallbash: right :wallbash: after :wallbash:.
I just never realized.

I removed this from the BuildInfo and now it works PERFECTLY!

Code:
<FeatureStruct>
   <FeatureType>FEATURE_FOREST</FeatureType>
   <PrereqTech>TECH_BRONZE_WORKING</PrereqTech>
   <iTime>300</iTime>
   <iProduction>30</iProduction>
   <bRemove>1</bRemove>
</FeatureStruct>

AVAIN YOU ARE THE GREATEST!!!
 

Attachments

It does pretty much what it sounds like: if it is True a message about completing the improvement is written to the log. If it is false, nothing is written to the log because the function exits before the CvUtil.pyPrint line is reached.
 
I revised mine to this

Code:
	def onImprovementBuilt(self, argsList):
		'Improvement Built'
		iImprovement, iX, iY = argsList
		pPlot = CyMap().plot(iX, iY)
		iNursery = CvUtil.findInfoTypeNum(gc.getImprovementInfo,gc.getNumImprovementInfos(),'IMPROVEMENT_NURSERY')
		if (iImprovement == iNursery):
			pPlot.setFeatureType(gc.getInfoTypeForString( "FEATURE_FOREST" ), 1, 1)
		if (not self.__LOG_IMPROVEMENT):
			return
		CvUtil.pyPrint('Improvement %s was built at %d, %d'
			%(PyInfo.ImprovementInfo(iImprovement).getDescription(), iX, iY))
and got this popup meaning I need to add another 1?


EDIT: ah, I see you've posted. So, great. DracoDruid you should post this as a modcomp in the downloads section.
 

Attachments

  • message.jpg
    message.jpg
    14.2 KB · Views: 103
I gladly will, but there might be one or two things left for perfection.

I will post new problems here or in another thread.
 
The error you got actually means you had one too many. The first part shows what you had in your Python, the second shows what the C++ end was expecting. (That first "CyPlot" argument is the "self" argument, which is automatically put in there for you and therefore is not in your code when you do the call.)
 
Ok here's the deal.

I want to integrate language-dependent Messages for Completion,
but my Python-Fu is not strong.

Maybe one of you can help me.

I want to replace the 'Terrain leveled' / 'New Forest planted' / etc.
Ingame Messages with placeholders like: "TXT_KEY_TREE_NURSERY_MESSAGE" from a new GameText.xml

But I don't know how to implement it correctly.
Just replacing them won't do it.
 
Converting the TXT_BLAH stuff to the actual text can be done via things like:
Code:
szText = CyTranslator().getText("TXT_BLAH", ())
This produces the text value for the tag in the current language.

In your examples it doesn't look like you have any, but if there are variables to be filled in in the text inside that second tuple argument (the "()") is where they go. With only one it would look like "(x,)" for two it would be "(x,y)" - single valued tuples are weird since they need a trailing comma so it knows you are building a tuple instead of using parenthesis for mathematical grouping purposes.
 
1) add to an XML file in the Text folder (or create a new file in the proper format) something like:
Code:
    <TEXT>
        <Tag>TXT_KEY_TREE_NURSERY_MESSAGE</Tag>
        <English>New Forest planted</English>
        <French>Nouvelle Forêts plantées</French>
        <German>Neuer Wald angepflanzt</German>
        <Italian>Nuova Foresta piantata</Italian>
        <Spanish>Los Bosques plantados</Spanish>
    </TEXT>
(Bad translations from Google Translate; wacky capitalization done to match the original. The two accented characters in the French version should be changed to #234 and #233, each with a leading "&" and trailing ";" - these originally were but this BBS actually translates those encodings to the single characters.)

2) change this:
Code:
CyInterface().addMessage(CyGame().getActivePlayer(),True,25,'New Forest planted','AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/TerrainFeatures/Forest.dds',ColorTypes(8),iX,iY,True,True)
to this:
Code:
[COLOR="Indigo"]szText = CyTranslator().getText("TXT_KEY_TREE_NURSERY_MESSAGE", ())[/COLOR]
CyInterface().addMessage(CyGame().getActivePlayer(),True,25,[COLOR="#4b0082"]szText[/COLOR],'AS2D_DISCOVERBONUS',1,'Art/Interface/Buttons/TerrainFeatures/Forest.dds',ColorTypes(8),iX,iY,True,True)
but with proper indenting.

3) Create some forests in game to test it.
 
doesn't sztext has to be defined as (string) variable somewhere?

Ok, I don't get it!?!

Everytime I edit the python file, the whole scripting won't work anymore.
Even if I delete all changes and revert the file back to before,
IT WONT WORK ANYMORE!

I have to replace the whole file with an unchanged one.
 
Do you see any variables being declared anywhere?

Well, OK: some are set to be empty lists, and such, so that their types are defined which allows you to append to the empty list.

But in general, no. Variables can be created on they fly anywhere in the program, no earlier declaration needed. Variables are set to the type of the object that you assign to them. You can even change them, if you have i = 1, making it an integer, you can then do i = "xyz" which changes "i" from an integer to a string.
 
It's hard to be sure why that would happen, but there is one possibility that comes immediately to mind.

In Python, the white space matters. That is, the "empty" space at the beginning of each line is important. The Python code that comes with Civ uses tabs to indent, so you should use tabs too. If whatever program you use to edit the files is changing tabs to spaces, make it stop.
 
Back
Top Bottom