Announcement

Collapse
No announcement yet.

No barbarians on ice

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • No barbarians on ice

    I hate the barbarians that get spawned from ice. Using python, it's a real mess to override the barbarian creation routines, since you have to rewrite everything.
    Using the SDK, however, it looks possible:
    In CvGame.cpp:
    Code:
    iNeededBarbs = ((pLoopArea->getNumUnownedTiles() / iDivisor) - pLoopArea->getUnitsPerPlayer(BARBARIAN_PLAYER));
     // XXX eventually need to measure how many barbs of eBarbUnitAI we have in this area...
    There's also an occurence for cities, but I've never been annoyed by barbarian polar cities so I don't care about these.
    There's also an occurence for animals, but polar bears are ok with me.

    So if I replace getNumOwnedTiles by getNumNotIceUnownedTiles, I'll be happy.
    (Well, not really, since looking for terrain in an area would require me to loop through the whole map everytime, thus I've got a small quadratic here, which stinks, but it's probably not going to slow down the game that much? Otherwise I'd have to rewrite the whole mess or cache the number of ice/not ice tiles... But performance tuning will wait.)
    Except how do I get the terrain type?
    getTerrainType returns that thing:
    Code:
    enum DllExport TerrainTypes
    {
    	NO_TERRAIN = -1,
    };
    What's that horror? An enum which is likely cast into a short. Mmmm... typedef anyone? What's the enum for?
    Anyway, I can get the TerrainInfo by getTerrainInfo(). So I just have to retrieve the "Ice" information from that.
    To that end, the best would be to mod the terrain files to add a tag to the ice terrain, (and maybe to desert? though deserts should spawn horse archers), and add the code to read it.

    I'm becoming too lazy to do that. I'm afraid it'll soon become a mess to merge this small change with changes to terrain files and the CvGame.cpp is also a big thing and I dislike the MS compiler enough that I'd rather not download it.

    But, well, it's possible. Does anyone else feel like doing it? Or using it if it gets done?
    Clash of Civilization team member
    (a civ-like game whose goal is low micromanagement and good AI)
    web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

  • #2
    Ok so I did it. If anyone's interested in testing, I'm attaching a zip with the 4 files I changed. I hardcoded the TERRAIN_SNOW as being no-barbarian. It might be slow on big maps, I havent tested big maps (my computer would crawl on big maps anyway).
    I can't post the dll as it's too big, so you'll have to recompile it.
    Attached Files
    Clash of Civilization team member
    (a civ-like game whose goal is low micromanagement and good AI)
    web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

    Comment


    • #3
      You know it strikes me that a better... well uh... one-line-wonder way would be to just add a pPlot terrain type comparison into one of the if statements - so basically, if it was about to create a barb unit in the snow, it gets cancelled. This might result in slightly fewer barbs being spawned though...

      My preferred way though would be to have ice tiles cause 5% damage per turn, so a barb (or anything!) coming from deep ice will be very fatigued.

      Comment


      • #4
        would be to just add a pPlot terrain type comparison into one of the if statements - so basically, if it was about to create a barb unit in the snow, it gets cancelled.
        That's actually a partly what I did. It was too boring to change the xml files so I just added a piece of info for TERRAIN_SNOW plots. I also added the part where I compute the number of non ice non visible plots, which is what can take some time. Now, considering they run about a hundred lookups for a suitable plot anyway, it's probably not that important to have less barbs.
        Having ice tiles deal damage wouldn't suit me here, although it' an interesting idea (it's in c-evo if you ever played that, but it's more than 5% in deserts I believe). Ice would still spawn barbs who can raid and ruin your cities too near the arctic.
        Clash of Civilization team member
        (a civ-like game whose goal is low micromanagement and good AI)
        web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

        Comment


        • #5
          What about changing this to force barbarians to spawn in a single terrain type (as well as goodies huts)?

          The C4:AC would definitely be interested to allow Mindworm spawning in fungus (jungle).
          Ceeforee v0.1 - The Unofficial Civ 4 Editor -= Something no Civ Modder should ever be without =- Last Updated: 27/03/2009
          "Just because I'm paranoid doesn't mean there's no conspiracy"

          Comment


          • #6
            MMC, That's pretty easy. I limited to all terrain but ice, but you can easily change that:
            I added
            Code:
            #define RANDPLOT_NOT_ICE (0x00000080)
            in CvDefines.h
            and use i in CvMap.cpp:
            Code:
            CvPlot* CvMap::syncRandPlot(int iFlags, int iArea, int iMinUnitDistance, int iTimeout)
            {(...)
            			if (bValid)
            			{
            				if (iFlags & RANDPLOT_NOT_ICE)
            				{
            					TerrainTypes ice = (TerrainTypes)GC.getInfoTypeForString("TERRAIN_SNOW");
            					if (pTestPlot->getTerrainType() == ice)
            					{
            						bValid = false;
            					}
            				}
            			}
            So you can alter that to be the kind of terrain you like. As I dais, it would be prettier to make the research criterion based on xml in order to allow for more flexibility but I was lazy.
            I then added the NOT_ICE there
            Code:
            void CvGame::createBarbarianUnits()
            {(...)
            	pPlot = GC.getMapINLINE().syncRandPlot((RANDPLOT_NOT_VISIBLE_TO_CIV | RANDPLOT_ADJACENT_LAND | RANDPLOT_PASSIBLE | RANDPLOT_NOT_ICE), pLoopArea->getID(), GC.getDefineINT("MIN_BARBARIAN_STARTING_DISTANCE"));
            The other change being that:
            Code:
            iNeededBarbs = ((pLoopArea->getNumNotIceUnownedTiles() / iDivisor) - pLoopArea->getUnitsPerPlayer(BARBARIAN_PLAYER))
            where getNumNotIceUnownedTiles has been added in CvArea.cpp.

            To sum up, you could use a flag in syncRandPlot that checks whether the terrain is valid or bears a goody hut, and add that flag in createBarbarianUnits.
            Clash of Civilization team member
            (a civ-like game whose goal is low micromanagement and good AI)
            web site http://clash.apolyton.net/frame/index.shtml and forum here on apolyton)

            Comment

            Working...
            X