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

An Idiots Guide to Editing the DLL

Discussion in 'Civ4 - Modding Tutorials & Reference' started by xienwolf, Mar 16, 2009.

  1. phungus420

    phungus420 Deity

    Joined:
    Mar 1, 2003
    Messages:
    6,296
    Thanks xienwolf. Once I get the install script squared away, I will move onto this. Have alot of Dll stuff I need to do, most of it relateing to CvGameTextManager, which i should be able to figure out, but given the sheer amount of stuff I plan on working on, I'm sure a non programmer like myself will have a few questions.
     
  2. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
  3. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    Well, I wouldn't mind seeing the bUnique tag finished up sometime in the nearish future (doesn't have to be now, but within a 2-3 months would be nice) as I'm planning on using it in future versions of Star Trek. But feel free to add other stuff in the meantime.
     
  4. cyther

    cyther Lord of the Dance

    Joined:
    Jun 9, 2008
    Messages:
    1,033
    Location:
    Fane of Lessers
    I'd like to say thanks, Xienwolf. This guide was really helpful in teaching me how to mod the DLL.
     
  5. Opera

    Opera Deity

    Joined:
    Sep 21, 2008
    Messages:
    4,643
    Gender:
    Female
    Very useful thread :) I don't remember posting here even though I read it many times already...

    One thing I'm looking forward to is array tag creation. I'm learning everyday how to mod the DLL by reading it and copying and etc. but I fear to try to create an array :lol:
     
  6. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    I held off on those for quite a while myself when I was learning the ropes. In the end I still don't really use them, since I wound up teaching myself vectors and lists first and vastly prefer using them to arrays :)

    Hopefully this weekend I'll be able to set aside some time to write up a bit more, at the least finish up the bUnique tag which I apparently stopped mid-write on.
     
  7. Opera

    Opera Deity

    Joined:
    Sep 21, 2008
    Messages:
    4,643
    Gender:
    Female
    I don't know how vectors work either. Are PrereqBuildingORs vectors? Lists?

    Anyway, I hope you find time. It's somewhat selfish to hope that but I'd like to see your thread resumed. There's a lot to learn from you :)
     
  8. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
  9. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    bUnique tag walkthrough is now complete. Any requests for the next field I work on (specific field or even just which type of field, new or import, string, int or array...)?

    Not sure when I'll get the time for it, but I plan to be somewhat brief and write it on the fly when I do get the time.
     
  10. Opera

    Opera Deity

    Joined:
    Sep 21, 2008
    Messages:
    4,643
    Gender:
    Female
    Well, you know it already: I'd like to know more about arrays, like the one used in BuildingInfos for RiverPlotYieldChange... but for, say, Hills or even a specific terrain.
     
  11. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    Arrays sound good, especially since there aren't any existing tutorials with them (at least that I know of).
     
  12. phungus420

    phungus420 Deity

    Joined:
    Mar 1, 2003
    Messages:
    6,296
    One of the Yield Arrays I was interested in working on was an effect from a tech or civic where Trade Route Yields would start producing :hammers: and :food: as well as the standard :commerce:. not sure if I would really use it though, but it seems like an interesting bit of code to set up, and the basic principle could be useful for other things.
     
  13. deanej

    deanej Deity

    Joined:
    Apr 8, 2006
    Messages:
    4,859
    Location:
    New York State
    Thankfully the traits already have that, so you would just have to clone it into the tech/civic area.
     
  14. phungus420

    phungus420 Deity

    Joined:
    Mar 1, 2003
    Messages:
    6,296
    Hmm, I didn't think <TradeYieldModifiers/> would work because in the default game trade routes only yield :commerce: and multiplying a percent of 0 will still always return zero. Anyway, that's not really important, I'm sure there are plenty of good ideas for arrays.
     
  15. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    You are actually talking about Structures with the specifics of what you said, but mostly that is from not understanding what you are asking for just yet :) But basically it is a no-no to mix types of items into a single field unless you want to get REALLY complicated (like my CityBonuses in Promotions, that required a Structure, and was a PITA) Well, unless you actually MEANT to ask about doing two seperate arrays, then it is still just an array.

    I'll probably do Yields for the Copy an existing function setup, since it is halfway done for you, then I'll make up something for the create your own which requires some serious loading work-arounds.

    Actually it will work perfectly. Your trade yields are a raw number, and are multiplied by what is listed in your TradeYield framework. By default you get 100 in Commerce, so all your yields are commerce. But with a default BtS civic you can add Food and Production to Yields from Traderoutes by just giving them values in that array.

    I don't know if the TradeYieldModifiers exists in Technologies already, maybe I'll port it from Civics to Techs for the Array Copy.
     
  16. Gooblah

    Gooblah Heh...

    Joined:
    Jun 5, 2007
    Messages:
    4,282
    Xienwolf, any thoughts about the functions of CvPlot/CvMap (i.e what they control, etc)?
     
  17. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    Lotta functions there, so lots of thoughts on them :) It's a pretty broad question that you ask.

    As a general overview of what each file controls, CvPlot holds data about the route/terrain/feature/bonus/improvement on a tile, and links to data on what units are present. CvMap is mostly just used by the main engine to control things like the fog of war, cloud overlay, and information layers, but it also has some search functions built into it.

    I would say that if you are thinking of making modifications to how land/water work, you'll find yourself mostly working in CvPlot. If you are doing a graphical overhaul of the base engine, then you'd be mostly in CvMap.
     
  18. phungus420

    phungus420 Deity

    Joined:
    Mar 1, 2003
    Messages:
    6,296
    Xienwolf, Cybah just made an interesting report:

    Python Callbacks cause significant slowdown

    Now for Legends of Revolution, it uses the RevDCM core which only has one python callback function it uses, specifically cannot train for the inquistor. I'd like to set up a tag for required civics that will eliminate the need to use this callback. It seems to me the best way to do this would be to use a setup like the SeeInvisible tag which I believe is a vector. Unfortunately you haven't covered this yet. Basically it would be best is to have it work so that if nothing is specified the unit could be trained under any civic condition, but if something is specified then the unit may only be trained while running those civics (which would require the ability to list mulitiple civics, prefferably in a way similar to how you can define mulitple SeeInvisible types). Any chance you could explain vectors, and give direction on how to start on such a task?
     
  19. xienwolf

    xienwolf Deity

    Joined:
    Oct 4, 2007
    Messages:
    10,589
    Location:
    Location! Location!
    Yes, the entire reason that the Callback file was created was Kael having discovered the immense processor toll taken by some callbacks which were running to BLANK python (but still cost a LOT, just to find out they were blank). So the Callback XML was generated so that BtS could remove this major lag source, but modders who were afraid of the DLL could easily bring back the few which they couldn't live without. This is one of the MAJOR reasons why I insist that DLL modding is superior to python modding. These areas of the code which run frequently run almost instantly in the DLL, and drag out in python.


    I hadn't planned on covering vectors at all in the initial write-up of this tutorial. Most things you would think to use a vector for are best done as an array, or a list to save memory space. Vectors tend to confuse people who use your source because it isn't always obvious they are allowed to use it in that way (look at how often we get posts about the amazing new thing someone learned about SeeInvisible, or how few people know what we are talking about at all and will be looking it up shortly).


    To make the processing go quicker, you'll actually be wanting to toss in a boolean (not read from XML, but set while reading the XML) with the array, to signify the need to check civics at all.


    Unfortunately I have a HUGE test I am preparing for on the 17th and 19th, so I shouldn't devote the time I would need to writing up good information for you right now. But I will say that you should ignore the vectors and instead look at how m_piPrereqAndTechs or m_piPrereqOrBonuses are set up. Unfortunately the section in ::read(XML) will probably confuse you to no end, that is the kind of thing I was planning to walk through slowly in the "Create your own array" when I got to it, but I got swamped midway through the Copy Array writeup. Though what I have on that so far might be of help to you (I wasn't going to announce I had done any work on it till I was done, but I am mostly complete already with it).


    Here is the section I anticipate you having problems with:

    Code:
    	if (gDLL->getXMLIFace()->SetToChildByTagName(pXML->GetXML(),"PrereqBonuses"))
    	{
    		if (pXML->SkipToNextVal())
    		{
    			iNumSibs = gDLL->getXMLIFace()->GetNumChildren(pXML->GetXML());
    			FAssertMsg((0 < GC.getNUM_UNIT_PREREQ_OR_BONUSES()),"Allocating zero or less memory in SetGlobalUnitInfo");
    			pXML->InitList(&m_piPrereqOrBonuses, GC.getNUM_UNIT_PREREQ_OR_BONUSES(), -1);
    
    			if (0 < iNumSibs)
    			{
    				if (pXML->GetChildXmlVal(szTextVal))
    				{
    					FAssertMsg((iNumSibs <= GC.getNUM_UNIT_PREREQ_OR_BONUSES()) , "There are more siblings than memory allocated for them in SetGlobalUnitInfo");
    					for (j=0;j<iNumSibs;j++)
    					{
    						m_piPrereqOrBonuses[j] = pXML->FindInInfoClass(szTextVal);
    						if (!pXML->GetNextXmlVal(szTextVal))
    						{
    							break;
    						}
    					}
    
    					gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
    				}
    			}
    		}
    
    		gDLL->getXMLIFace()->SetToParent(pXML->GetXML());
    	}
    
    I briefly mention the SetToChild deal in the copy Array walkthrough, same thing here, you are "moving inside" the deeper layer of XML, so have to remember to move back out at the end with SetToParent. SkipToNextVal checks if there is anything else written within the current level of XML. GetNumChildren checks how many total things are written at this level. Ignore the Assert, it only matters when you do a debug DLL much later, InitList stores 0 values in the entire array so we can have meaningful data to start with. Next, the check for iNumSibs > 0 is redundant since we couldn't have 0 siblings and still have passed the NextVal check earlier. Then we load the value of the first child in szTextVal (notice that it doesn't matter at all what the child is called in the XML), again ignore the Assert message. Now a loop starts which will check what szTextVal matches (in this case a bonus, in your case a civic) and flags a boolean in our array as true which matches this civic. We then check if there is another XML value (there should be, unless one of those siblings was a comment) and prepare to load it next. It is a little confusing because the pXML->GetNextXmlVal(szTextVal) is actually changing the value of szTextVal while it runs, and then returns a boolean value as well.

    Anyway, you could use this exact routine copied and change the variables for the array to something properly civic-named, and the name of the piece in quotes at the top to what you use in the XML for your new field. Compare the Tech with the Bonus to see precisely what to change and where.


    I had mentioned also setting up a boolean value during this array. It would just be a method of speeding up the code even more than normally done, at the minor cost of a bit more savegame size (a VERY minor cost). But I haven't really time to get into how to do that.

    I am not sure if there are any good examples of a loop over all civic types in the code for you to build the actual functional pieces from. If there aren't and you don't hear from me in a semi-speedy manner when asking for more help, I do some things fairly similar to this in Fall Further, so you could grab our sourcecode and look at it for examples. I don't do this EXACT thing though, and am not sure if I have set up any arrays for civics, but I am reasonably certain that I did do some Civic arrays in PromotionInfos which you can check out. Actually, I am almost 100% certain that I have done so. But I used lists instead of arrays to save some memory in the savefile, and don't use the boolean trick I am alluding to on occasion because I hadn't thought of it yet and haven't had the time to retro-fit all of my code to use it for the performance boost.
     
  20. rockinroger

    rockinroger WoC Team Member

    Joined:
    Feb 6, 2006
    Messages:
    1,312
    Location:
    Overland Park, Kansas
    Excellent work. As someone trying to move from simple xml to more complex c++ and python, its greatly appreciated. Now maybe i can figure out what is causing this crash
    Spoiler :
    Code:
    int CvHotkeyInfo::getOrderPriority() const
    {
    	return m_iOrderPriority;
    }
     

Share This Page