Eunomiac's Strategy Layer

ruff_hi

Live 4ever! Or die trying
Joined
Oct 24, 2005
Messages
9,134
Location
an Aussie in Boston
Well - he did it again. Why isn't this guy on our R&D team? Better yet - why don't we strong arm him into learning python so he can answer his own needs!

Revamped Strategy Layer: The Holy Grail of BUG Mod features, so shrouded in distilled awesome that I had resigned myself to its impossibility. The strategy layer as-is sucks. No, that's being generous: it's the crowning embarrassment of the Civ franchise. The most sophisticated strategy game in computer history offers a strategy layer that can't be viewed in combination with resource flagging, can't be viewed zoomed-in, has a cloud layer obscuring everything by default and provides a single crayon for your planning. Here is what I would step over my own mother to see:
  • a city BFC shape that you can plop down in the strategy layer, for in-game dot-mapping. That hashed BFC overlay that appears when you select a Settler would be perfect.
  • little tokens you can drop on tiles to identify things like which forests you want to save for lumbermills, or farms you want to switch to watermills, or blockade points for military invasion, etc. These tokens could be as simple as circles with the letters of the alphabet in them, leaving remembering what means what to the player.
  • the ability to hide the strategy layer when you don't need it
  • the ability to flag resources (Ctrl-R) while in the strategy layer
  • the ability to zoom in with the strategy layer active

This looks pretty interesting. Apart from the BFC graphic, couldn't all of these items be handled with flags? I note that EF mentioned Dresden's event flags ...
Spoiler link to event flags :
I really wish someone would add Event Signs to BUG. Anyone up for this? It would be really easy to add it to the new BUG core and would provide a guinea pig valuable modder feedback on the new process. ;)
So, Dresden has worked out how to add flags using python. So, we just store all this stuff and create a hot key to toggle the strategy layer (ie lots of flags) on and off. Easy! You toggle into the strategy layer, get a big fat statement along the top 'Strategy layer' or remove the interface (Alt-I like), add flags for what ever you want to add, hit the toggle and flags go away, interface comes back ... on you go.

Just have to figure out how to do the BFC. Is this somehow linked to settles only? In xml unit info?

Edit: if (when) we do this - we should make it a stand along mod so everyone can add it to their mods.
 
maybe we can intercept the alt-s call and have a dialog box that asks for 'text' and category (military, econ, resource, tile, etc, etc - user defined and user color coded) and then adds a flag of the appropriate color.

For the BFC - and assuming that this graphic is linked to a unit, create a new unit with no art work (game automatically creates a pink dot!) and have the color linked to the number of units of this type (1st = pink, 2nd = red, etc). This unit only appears in the strategy layer, cannot move, etc, etc.
 
Another quality suggestion. I looked into making a BFC dot mapper several months back, but there doesn't seem to be a way to access the lines via CyEngine as you can signs.

So I looked at the other methods of CyEngine (used by AStarTools's move highlighter) and found this gem:

Code:
addColoredPlotAlt(INT plotX, INT plotY, 
                  INT iPlotStyle, INT iLayer, 
                  STRING szColor, FLOAT fAlpha)

x, y, color and alpha seem to be what they suggest, and some layers remain visible while others disappear as soon as you select a unit. But I wonder what kind of styles you can have . . .

Spoiler Hang on to your hat! :

The 27 style choices
Many are clearly useless for us, but there are quite a few handy ones from which to choose. As Ruff already states, we can also use signs. And we can easily store these in data structures so we can show/hide them at-will.

As for altering the interface, I think Ruff has the right idea: swap to minimal interface mode (CTRL + I) and add some buttons for placing objects.

Edit: I should point out that we can assign any color to any tile overlay along with an alpha value (% transparency). This would allow us to color overlapping city areas in a dot map with different colors. Maybe some of the icons could serve as standard markers.
 
Better yet - why don't we strong arm him into learning python so he can answer his own needs!

@Eunomiac - If you have an interest, I'll gladly help you learn Python. I am already helping NikNaks and Cammagno, but it turns out they didn't need much help. :D
 
I like those graphics a lot, EmperorFool — being able to drop those at will in the strategy layer would be amazing! Will we be able to design our own when creating this feature for BUG, or are we limited to using the existing ones? In an ideal world, I'd love if they were a bit smaller (so you could leave them on at all times, just as a reminder not to chop that forest or whatever), but as I said they're still awesome if not :)

As for the BFC, the Settler hashed BFC is solid, but if it's possible to design our own I'd prefer something a little less obtrusive — just the outline, perhaps, with a letter in the middle to indicate the location of the city.

I'm pretty decent with graphical stuff, and would be able to design a few of these icons in whichever format is needed.

EmperorFool said:
If you have an interest, I'll gladly help you learn Python. I am already helping NikNaks and Cammagno, but it turns out they didn't need much help.

Yeah, I'd definitely like to learn python for Civ IV, and would appreciate any help you could give me! I have a ton of ideas of stuff I'd like to mod, especially as regards the diplomacy system. I've been going through a bunch of tutorials, but I don't think 'print "Hello World!"' is all that helpful for Civ IV :p Trying to understand something as simple as the Alt-M reminder code made my head spin, what with all the Civ-specific event manager and triggering stuff.
 
I would absolutely love it if I could change those graphics. They are simply the choices given to me in the code. As everything else graphical in Civ can be replaced, I hope these can as well.

Woot! :goodjob:

"Art\Terrain\PlotTextures" contains all the overlays. They are invisible in IrFanView, but GiMP shows them just fine (probably white for easy color application).

We'll probably be limited to the number (27) of total overlays, but that gives us a lot of wiggle room. I haven't found a way to create the city border effect shown when a Settler is selected, but that would be ideal of course.

I was thinking for city borders you'd want each dot to be a different color with an optional sign to label it. Where two or more cities overlap, the shading could be darker.

Heck, this mod is gonna be a blast to write! I didn't know there were so many overlays to choose from, and now that we can swap in our own . . . lots of possibilities.
 
Good job EF! This does indeed look like fun stuff. Here is an example of the other kind of overlay, the one the game uses to show settlers and naval blockades. It uses CyEngine.fillAreaBorderPlotAlt(). I don't see that one in the Python API (even in EF's updated one) but I found it in the worldbuilder code for both the brush cursor and reveal plot mode. Here is the results of a quick test (Images link to full-size):

Before:


Following code applied:
Spoiler :
Code:
from CvPythonExtensions import *

# globals
gc = CyGlobalContext()
engine = CyEngine()

LAYER = AreaBorderLayers.AREA_BORDER_LAYER_WORLD_BUILDER

def clear():
    engine.clearAreaBorderPlots(LAYER)

def drawBFC(x, y, color):
    for iX in range(x-2,x+3):
        for iY in range(y-2,y+3):
            if not ( (iX == x-2 or iX == x+2) and (iY == y-2 or iY == y+2) ):
                engine.fillAreaBorderPlotAlt(iX, iY, LAYER, color, 1)

drawBFC(19,41,"COLOR_GREEN")
drawBFC(23,39,"COLOR_BLUE")
drawBFC(26,42,"COLOR_MAGENTA")
drawBFC(28,39,"COLOR_WHITE")

After:


Overlap is a little weird when you have different colors on the same layer, but it increases our options some.

Note, the defined border layers are:
Code:
	python::enum_<AreaBorderLayers>("AreaBorderLayers")
		.value("AREA_BORDER_LAYER_REVEALED_PLOTS", AREA_BORDER_LAYER_REVEALED_PLOTS)
		.value("AREA_BORDER_LAYER_WORLD_BUILDER", AREA_BORDER_LAYER_WORLD_BUILDER)
		.value("AREA_BORDER_LAYER_FOUNDING_BORDER", AREA_BORDER_LAYER_FOUNDING_BORDER)
		.value("AREA_BORDER_LAYER_CITY_RADIUS", AREA_BORDER_LAYER_CITY_RADIUS)
		.value("AREA_BORDER_LAYER_RANGED", AREA_BORDER_LAYER_RANGED)
		.value("AREA_BORDER_LAYER_HIGHLIGHT_PLOT", AREA_BORDER_LAYER_HIGHLIGHT_PLOT)
		.value("AREA_BORDER_LAYER_BLOCKADING", AREA_BORDER_LAYER_BLOCKADING)
		.value("AREA_BORDER_LAYER_BLOCKADED", AREA_BORDER_LAYER_BLOCKADED)
		.value("NUM_AREA_BORDER_LAYERS", NUM_AREA_BORDER_LAYERS)
		;
 
It uses CyEngine.fillAreaBorderPlotAlt().

$&*#@ ya! Good job on finding that, and thank you for pointing out where you found it. I should do a quick grep of the Python codebase for any other uses of CyEngine. I was wondering how the original API script at Apolyton had found the functions he has.

This explains why he didn't have any parameter names: he was just counting the parameters in the Python calls.

This will be even better than what I was going to do: create the 12 possible border combinations (left, right, top, bottom, topleft, topright, etc.) for building a city. I'd vastly prefer to let the engine do it for me. :)

Also, I'm really hoping that the definitions of the overlay images is in XML. If it is, I can add more than 27. I can see #s being useful, so 20 would allow 100 numbers (10 digits on the left, ten digits on the right, 100 combinations). We'll want a city outline (on just the 1 plot, like a faded village or something), plus various other markers: rally points, blockade areas, sentry locations, fort locations, future improvements, etc.)

This could even then be expanded to semi-automate workers. You put workers under BUG's control and mark the improvements you want built ahead of time. Then the workers that you have given to BUG would build those improvements in some semi-reasonable order. I'd also like the ability to mark up the improvements I plan for a future city and be able to see the output of the city.

I had always considered marking up the map in any decent sort of way impossible, but no more. Wow wow wow! Thanks Eunomiac! You kicked off something pretty great here. :goodjob: And I'm hoping you, Dresden, might be interested in working on this too.

This will make a great multi-person project. Most of the BUG stuff so far has been individual mods put together. Sure, we've given each other input along the way, but most everything has been small enough for one person to tackle. This could grow to be much bigger I hope. :D
 
$&*#@ ya! Good job on finding that, and thank you for pointing out where you found it. I should do a quick grep of the Python codebase for any other uses of CyEngine. I was wondering how the original API script at Apolyton had found the functions he has.

This explains why he didn't have any parameter names: he was just counting the parameters in the Python calls.
The only "new" ones I've found are all related to these filled areas with borders:
Code:
void clearAreaBorderPlots( int iAreaBorderLayer )
void fillAreaBorderPlot( int plotX, int plotY, NiColorA color, int iAreaBorderLayer )
void fillAreaBorderPlotAlt( int plotX, int plotY, int iAreaBorderLayer, string szColor, float fAlpha )

Note that the graphics for these filled areas are in Art/Terrain/PlotTextures/AreaBorder.dds

continued... said:
Also, I'm really hoping that the definitions of the overlay images is in XML. If it is, I can add more than 27. I can see #s being useful, so 20 would allow 100 numbers (10 digits on the left, ten digits on the right, 100 combinations). We'll want a city outline (on just the 1 plot, like a faded village or something), plus various other markers: rally points, blockade areas, sentry locations, fort locations, future improvements, etc.)
Neat ideas, but I think we might be limited to the 27 since the enumeration is completely listed in the SDK:
Spoiler :
Code:
//Warning: these values correspond to locations in the plot texture [JW]
enum DllExport PlotStyles						// Exposed to Python
{
	PLOT_STYLE_NONE = -1,

	//first row
	PLOT_STYLE_NUMPAD_1 = 0,
	PLOT_STYLE_NUMPAD_2,
	PLOT_STYLE_NUMPAD_3,
	PLOT_STYLE_NUMPAD_4,
	PLOT_STYLE_NUMPAD_6,
	PLOT_STYLE_NUMPAD_7,
	PLOT_STYLE_NUMPAD_8,
	PLOT_STYLE_NUMPAD_9,

	//second row
	PLOT_STYLE_NUMPAD_1_ANGLED = 8,
	PLOT_STYLE_NUMPAD_2_ANGLED,
	PLOT_STYLE_NUMPAD_3_ANGLED,
	PLOT_STYLE_NUMPAD_4_ANGLED,
	PLOT_STYLE_NUMPAD_6_ANGLED,
	PLOT_STYLE_NUMPAD_7_ANGLED,
	PLOT_STYLE_NUMPAD_8_ANGLED,
	PLOT_STYLE_NUMPAD_9_ANGLED,

	//third row
	PLOT_STYLE_BOX_FILL = 16,
	PLOT_STYLE_BOX_OUTLINE,
	PLOT_STYLE_RIVER_SOUTH,
	PLOT_STYLE_RIVER_EAST,
	PLOT_STYLE_SIDE_ARROWS,
	PLOT_STYLE_CIRCLE,
	PLOT_STYLE_TARGET,
	PLOT_STYLE_DOT_TARGET,

	//fourth row
	PLOT_STYLE_WAVES = 24,
	PLOT_STYLE_DOTS,
	PLOT_STYLE_CIRCLES,
};
continued... said:
I had always considered marking up the map in any decent sort of way impossible, but no more. Wow wow wow! Thanks Eunomiac! You kicked off something pretty great here. :goodjob: And I'm hoping you, Dresden, might be interested in working on this too.

This will make a great multi-person project. Most of the BUG stuff so far has been individual mods put together. Sure, we've given each other input along the way, but most everything has been small enough for one person to tackle. This could grow to be much bigger I hope. :D
I'm sure I can chip in on this. :)
 
The only "new" ones I've found are all related to these filled areas with borders

I'll add those to the API script. Thanks.

Note that the graphics for these filled areas are in Art/Terrain/PlotTextures/AreaBorder.dds

Yes, I saw that when I found the others. It's interesting to see that they are drawn overlapping the borders of tiles. This explains the screenshot you posted, how different colored areas met in the middle of a tile.

Hmm, how did you draws those BFCs in WB? The only thing I can find is setting culrural ownership.

Neat ideas, but I think we might be limited to the 27.

Yup, I tried using 27 as a value, but nothing gets drawn. At least it doesn't CTD tho. :) Yet another cool thing we could do with our own DLL.
 
Yes, I saw that when I found the others. It's interesting to see that they are drawn overlapping the borders of tiles. This explains the screenshot you posted, how different colored areas met in the middle of a tile.
Just throwing this out there - check the 'z' value which controls how 'high' off the ground it is. Or swap to satellite view (ctrl-F) and see it that lines the colous up with the lines.
 
Just throwing this out there - check the 'z' value which controls how 'high' off the ground it is. Or swap to satellite view (ctrl-F) and see it that lines the colous up with the lines.

There's no z parameter to specify. What I mean is that the overlay icons themselves are made up of the four corners where four tiles come together. This allows a single overlay icon to have the curved "bridged corner" effect when two diagonal tiles have the overlay but the other two do not:

Code:
#########
#########
#########
##########
##########
#############
#################-------- <- tile border
    #############
       ##########
       ##########
        #########
        #########
        #########
        |
        |
        |
        | <- tile border
 
Hmm, how did you draws those BFCs in WB? The only thing I can find is setting culrural ownership.
I didn't actually use WB to do the drawing, I just more-or-less randomly chose the WB layer for my test. That code snippet in my spoiler was saved as the file BFC.py and I just loaded a save, imported BFC in the console, and everything got drawn. Calling BFC.clear() and BFC.drawBFC() let me experiment further.

My guess is that the different layers are always visible but that when the game needs a certain layer (e.g. the WB layer when you open it up or the 2 city radius layers when you select a settler) it generally clears the whole thing, draws what it needs, and then clears it again when its done. So our choices for layers to use would be those that we are most easily able to test when they are active so that we can save off our own stuff beforehand and then restore it as necessary.
 
I didn't actually use WB to do the drawing, I just more-or-less randomly chose the WB layer for my test. That code snippet in my spoiler was saved as the file BFC.py and I just loaded a save, imported BFC in the console, and everything got drawn. Calling BFC.clear() and BFC.drawBFC() let me experiment further.
say what? the console? and you imported py code into the game on the fly ... interesting.
 
Oh yeah. I love the Python console (the one you access with "~"; make sure you see the Python version info and the ">>" prompt when you start it). Wonderful debugging tool for doing things like this or other experiments such as forcibly triggering "random" events.

If you call functions that normally print to the debug log, their output shows in the console too. So it was pretty handy when working on the favorite-civic stuff as I could force updates and see the data structure output while in-game.

Importing a module on the fly was a trick I learned when I couldn't figure out how to do multi-line code (like a simple for loop) directly in the console. Instead, I just alt-tabbed out, put my code snippet in a text file in the custom assets directory, and then imported it. :D
 
the one you access with "~"; make sure you see the Python version info and the ">>" prompt when you start it.

And you need to put the cheat (chipotle) code into CivIV.ini IIRC.

I couldn't figure out how to do multi-line code (like a simple for loop) directly in the console.

I've done single multi-line blocks like this:

Code:
for k in d: print k

but if the block of code inside your loop is multi-line itself, I think you can use ; to separate lines:

Code:
for k in d: k = k.tolower(); print k

[Yes, I know you can "print k.tolower()" -- it's an example.]

I've played around with adding BFC's now as well, but it's really hard to see how cities will overlap. You can see it in your screenshot: which tiles will the various cities share? What I was thinking (though it would be a PITA to code up) was creating all the needed outline possibilities in the tile overlays (PlotStyles) I posted earlier. You would build them up to look like this:

Code:
  +-----+
  |     |
+-+     +-+
|         |
|       +-+---+
|    A  | |   |
|     +-+ |   +-+
|     |   |     |
+-+   | +-+     |
  |   | |  B    |
  +---+-+       |
      |         |
      +-+     +-+
        |     |
        +-----+

It's easier to see here that the two cities share 4 tiles as compared to the same situation here:

Code:
 ###
#####
##A##XX
#####XXX
 ###XBXX
   XXXXX
    XXX

Here you can see that they overlap, but it's difficult to tell at a glance which tiles they will share. I don't dot map much (I just mark the cities with signs), but I know it's a PITA to constantly work out which tiles a city will work.

So the filled areas look nicer (hashing fill and rounded-corner contiguous borders), but it's tough to see overlap since, well, there is none. Now, there are multiple layers, and they're probably drawn separately. You can see the barbarian city's borders underneath Dresden's dot-mapped cities pretty well. We could put adjacent cities onto different layers (similar to the "four-color map problem" I suppose).

I'll play around with some more code. Hmm, I really need to commit the new core. So little time! :cry:
 
This will make a great multi-person project. Most of the BUG stuff so far has been individual mods put together. Sure, we've given each other input along the way, but most everything has been small enough for one person to tackle. This could grow to be much bigger I hope. :D
I'm happy to be Mr QA, sounding board, general direction pointer (not setter!), what-about-such-and-such and all-purpose-that-sucks-make-it-better person.
 
[...]what-about-such-and-such and all-purpose-that-sucks-make-it-better person

I'm absolutely positive you can fill this role perfectly :D :p
 
Well, I would love to help you, but my code abilities in Python are null ( well, I know fortran, Matlab and Pascal and it does not look too dificult to use python ( besides the spaces/tabs issue ) ..... surely not as hard as Fortran :wallbash: . But I don't code for quite a while and I'm seriously rusty :( ). May I get the role that Ruff is apllying to ? :p
 
EmperorFool said:
This could even then be expanded to semi-automate workers. You put workers under BUG's control and mark the improvements you want built ahead of time. Then the workers that you have given to BUG would build those improvements in some semi-reasonable order. I'd also like the ability to mark up the improvements I plan for a future city and be able to see the output of the city.

Okay, I promise you this was going to be my next suggestion — except my idea was to have a new unit command on workers that brought up a variation of the city screen, centered on the worker, within which visible squares could be flagged for certain improvements. I thought this might be a little easier to program, as this "worker screen" could be self-contained, converting into a simple string of queued worker actions upon exit.
 
Top Bottom