RFC w Ireland v1 ...new civ, new flag, new everything...well, almost everything

well, first, I'll make note of the khmer cities and add them to barbs.py so they spawn at the right times. When the final release comes out (I believe as soon as I get this UHV thing sorted out) they will be included.

As for the marathon mod, I used the existing RFC Marathon mod v3. It has its own thread in this forum http://forums.civfanatics.com/showthread.php?t=354241
 
Baldyr, should this work?

setting:
tBritishIslesTL = (47, 53)
tBritishIslesBR = (55, 61)

Spoiler :


if (iGameTurn == getTurnForYear(1700)):
bForeignPresence = False
#British Isles
for x in range(tBritishIslesTL[0], tBritishIslesBR[0]+1):
for y in range(tBritishIslesTL[1], tBritishIslesBR[1]+1):
pCurrent = gc.getMap().plot(x,y)
if (not pCurrent.isWater()):
for iLoop in range(iNumMajorPlayers): #no minor civs
if (iLoop != iKhmer):
if (pCurrent.getCulture(iLoop) > 0):
bForeignPresence = True
print (iPlayer, "presence in British Isles")

print ("bForeignPresence ", bForeignPresence)
if (bForeignPresence == False):
self.setGoal(iKhmer, 0, 1)
else:
self.setGoal(iKhmer, 0, 0)


It represents a change in approach...England sealed its domination of Ireland by 1690...it didn't vassalize it, but ruled it with the one crown (although Ireland still had a parliament until 1800, so maybe that should be the date I use)...this UHV basically means having Ireland do to England what England did to Ireland. The UHV is trickier than it seems, once London is no longer a capital, Paris and Amsterdam tend to claim three or four tiles in southeast britain between them. Very hard to push that back...
 
Tell me you didn't just make that code yourself. :eek:

Because it seems about right to me. :goodjob: Except for this line, which is really redundant anyway:

print (iPlayer, "presence in British Isles")
Change iPlayer to iLoop and you'll be ok. :king:

One other thing, though. Please use the [ code ] tags whenever you're posting Python! Otherwise the indentation doens't show, and it will be impossible to both follow and proofread your code. Its not more work than to select the code and press the # symbol in the toolbar when composing your message.
 
ah, code tag...got it.

I can't take the credit, I didn't write it, I cannabalized from Japan.

Now, I have two questions. 1) from Rhye's wording of the Japanese UHV here: http://rhye.civfanatics.net/wiki/in...ivilization_Unique_Historical_Victories#Japan

("There may never be foreign culture in the Japanese main island.")

any presence of foreign culture before the trigger date will trigger failure? reading the code, it looks to me like only the state of things at the trigger date matters (which is what I want). for the Irish to never have any culture on the island would be a virtual impossibility, but it would be possible (though difficult) to ensure no foreign presence by 1700 or 1800.

2) I'm not sure what this [0], [1], and +1 business is in the code. is that somehow creating a loop that causes the game to walk through all the coords? Why aren't the coords simply taken as the TL/BR box that defines them up top?

also, why should I change iPlayer to iLoop? What is the effect of that (Rhye had iPlayer)?
 
1) from Rhye's wording of the Japanese UHV ...

("There may never be foreign culture in the Japanese main island.")

any presence of foreign culture before the trigger date will trigger failure? reading the code, it looks to me like only the state of things at the trigger date matters (which is what I want).
You are reading the code correctly, so the source would be wrong (or outdated) then. But the best way to check would be to test the code, I guess...

2) I'm not sure what this [0], [1], and +1 business is in the code. is that somehow creating a loop that causes the game to walk through all the coords? Why aren't the coords simply taken as the TL/BR box that defines them up top?
This was weird to me also in the beginning. :crazyeye: There is actually an explanation, but I'm afraid it's not a short one. :rolleyes:

Ok, the range command creates a list variable which contents are defined by the input. So if you, for example, go range(5) the Python interpreter will view it like this:
Code:
[0, 1, 2, 3, 4]
That is, a list (hence the brackets) with five values ranging from 0 to 4. We can add another value and then we get the first and the last value in range. So range(0, 5) would really be the exact same thing as above, as the first value will be 0 and the last will be the fifth value in order, counting from zero.

There are other ways of using the range command also, but this would be the most common one and the one you need to know about for modding purposes.

So, you have a list then, but how to make it into a loop? Well, you use the for and in commands for this. So if you go for iLoop in range(0, 5): then you will get five loops (the same as the length of the list, of course) where the iLoop variable changes from the first list value through to the last one.

Note that you're not limited to using range with for and if. This is another use:
Code:
list = [1, 3, 6]
for iVariable in list:
        ...
It should be obvious what it does, not?

Ok, moving on. The TL and BR values in RFC are "tuples", which is another sort of list really. You defined two tuples yourself:
Code:
tBritishIslesTL = (47, 53)
tBritishIslesBR = (55, 61)
You even used the common practice of including the "t" prefix to the variables. :goodjob:

Ok, so you got a pair of tuples containing a pair of values (coordinates in this case) each. How to get access to those values? Well, you use the brackets you were wondering about. tBritishIslesTL[0] is "47" as it is the first value (and the computer always indexes from zero and up) and tBritishIslesTL[1] is "53". Its the way to extract the values from the tuple.

You could have defined the coordinates with only one variable also:
Code:
tBritishIsles = (47, 53, 55, 61) #TL[0], TL[1], BR[0], BR[1]
or:
Code:
tBritishIsles = (47, 55, 53, 61) #TL[0], BR[0], TL[1], TL[1]
or even:
Code:
tBritishIsles = ((47, 53), (55, 61)) #TL, BR
Then it would just be a matter of figuring out how to extract those values and put them in the right place.

The way Rhye uses these tuples for looping coordinates is that he extracts the first values (the x coordinate) from each tuple and uses them with the range command. In a for-in statement this creates a loop, from the first value, through all the values in the list, all the way to the second value. Then he does the same thing with the second value in each tuple (the y coordinate) and creates another loop inside the first one. :eek: So all the y values would be looped for each x value, and when the first loop is completed all x and y coordinates would have been looped through. Makes sense? :p (In your case x gets looped from 47 to 55, and y gets looped from 53 to 61.)

So, have you figured out what the +1 does yet? If you can't, click on the spoiler. :rolleyes:
Spoiler :
You remember how the computer always counts from zero and up? So if you wanna create a list that holds say some x coordinates on the map, you have to add one to the second value. Otherwise the list will be missing the last value you requested.

Lets say you wanna create a list with values ranging from 1 to 10, ten values in all. Then you can't go range(1, 10), because the tenth value in order would be 9. So you'd end up with a list with 9 values instead:
Code:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
It all makes sense if you only use one value inside the command, like range(10). Then you get a list with ten entries:
Code:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

also, why should I change iPlayer to iLoop? What is the effect of that (Rhye had iPlayer)?
Ah, I wasn't looking at Rhye's code. I'm not sure if its intentional or not, but Rhye's code will always write "Japan presence in japan" which really isn't all that helpful for debugging... :rolleyes: I'd change it to iLoop myself - if I didn't delete (or comment out) the line entirely. Because the print command does nothing in CivIV - its only useful for debugging.

Anything else unclear at this point? Because you'll be reading Python in no time at all if you just make a point of understanding what is happening. Then you will be able to figure out how to code your own stuff. :king:
 
Just as trivia, I might add that there is another way of creating these loops for the coordinates:
Code:
iBritainTLx = 47
iBritainTLy = 53
iBritainBRx = 55+1
iBritainBRy = 61+1

...

for x in range(iBritainTLx, iBritainBRx):
        for y in range(iBritainTLy, iBritainBRy):
                pCurrent = gc.getMap().plot(x, y)
It might be a clearer way of doing it, even if it means more lines of code (variable definitions). But because its your code you can do it anyway you want to. :p

Further trivia:
Code:
lBritishTiles = [] [COLOR="DarkRed"]#creates an empty list[/COLOR]
for x in range(47, 56): [COLOR="DarkRed"]#loops though the x coordinates, with +1 on the second value[/COLOR]
        for y in range(53, 62): [COLOR="DarkRed"]#same for the y coordinates[/COLOR]
                lBritishIsles.append((x, y)) [COLOR="DarkRed"]#appends a tuple containing both values to the list[/COLOR]
for tCoords in lBritishTiles: [COLOR="DarkRed"]#loops the tuples in the list[/COLOR]
        pCurrent = CyMap().plot(tCoords) [COLOR="DarkRed"]#assigns pCurrent to each tuple in order[/COLOR]
        ...
In case you wanted more. :lol:
 
I'm hoping that the final release will contain three maps, 3000BC, 600AD and an American start (because it takes so long to get there on marathon. Right now, I'm testing something that starts in 1450, so that the American player always comes to a slightly varied world.

I'm getting lots of EOFErrors relating to the stability of existing civs, however, so I don't know if it will be possible (starting with active major civs on the map, that is).
 
I'm getting lots of EOFErrors relating to the stability of existing civs, however, so I don't know if it will be possible (starting with active major civs on the map, that is).
Yeah, I have no idea what that is all about. Someone posted an American start before and when I tested it there were these errors all over the place. I narrowed it down to the values Rhye pickles and unpickles. The default values are found in StoredData.py and they are accessed with the functions that start with "get" and "set" (to fetch and to store respectively).

It could be that the whole thing isn't initialized properly, so any pickling (like with the stability settings) wouldn't work. It could be as easy to modify one single line of code or to add a line of code somewhere - or it could be a much bigger project. Pickling itself is something I'm yet to really get into myself, so I wouldn't be much help I'm afraid.

With this said, I believe that the initialization is configured in CvRFCEventHandler.py - with the line:
Code:
                self.data.setupScriptData()
That refers to the StoredData module (by self.data = StoredData.StoredData()) and the function setupScriptData() works just the same with both default scenarios. (It would, however, be possible to add another set of values specific to, say, a AD 1450 scenario. Rhye tweaks the default values for the AD 600 scenario in RiseAndFall.py with the setup() function, by the way. So this is the other option.)

I'm thinking that it would be more to it than to just make a save into a WBS. Right now the code is facilitating two different scenarios (3000 BC and AD 600) and I believe that the whole thing would have to be overhauled with a third scenario in mind. There could also be stuff in the DLL that I wouldn't be aware of.

As people have pointed out elsewhere on this forum, something like a AD 1500 scenario would pretty much be its own beast. A modmod, really. Why not save that one for later?
 
yeah, I think it has to do with all kinds of crazy stuff I haven't the patience to get into right now.

Still, I wonder if it wouldn't be possible to put in a blank map with all the improvements (but no civs) and simply use barbs.py to spawn every city with appropriate owners during the second turn of the autoplay (or something similiar). Maybe all indy cities and then your custom.fliparea function to spawn every civ at once?

There would need to be a more sensible way to flag that the 1450 scenario is what's being played, however, than the one Rhye used in seeing if an ancient civ was dead. He used the Egyptians, did he not? (actually, I think I just read that Rhye was a "she" not a "he"...but I have been unable to confirm this). In any event, perhaps I could start the whole world with just indy cities and script one massive, worldwide set of spawns if "China" is "dead" at the start (and player is "America")...that way, the game would know not to do the flips for the 3000BC or 600AD starts... I may have to have some civ alive on the map at the start though, I'd imagine...perhaps the Mongols...then the China flip will cause them to collapse and go byebye.

Well, I suppose I should try it without any civs alive at the start first (save the natives, indies and barbs).

Does that sound plausable, or am I totally barking up the wrong tree?
 
Well, it does sound... interesting, at least. Please keep us posted on how this experiment or yours develops.

I'm working on some new tools for scenario making, by the way. But you can find the latest version of the old functions here. The documentation can be found in this thread, scattered around as development has progressed.

Also, I may eventually device a text based setup that looks something like the "code" that makes up the World Builder Save file. So there would be no need to learn any Python or XML or anything. :king:
 
"Also, I may eventually device a text based setup that looks something like the "code" that makes up the World Builder Save file. So there would be no need to learn any Python or XML or anything."


now THAT would be a service to humanity. Hey, considering the low standards for the Nobel Peace Prize nowadays, you never know ;)
 
:lol:Heh, this would be the default way to define a scenario trigger (in Python):
Code:
Trigger(2).turn(65).valid().city(104, 45, "Qufu")
Its just an example and it will spawn a Chinese size 2 city called "Qufu" on tile 104, 45 at turn 65. (There are a lot more that could be done, and many more settings that are available to the scenario designer, by the way.) The point is however that there is no need to do any other code, worry about any indentation or anything.

Ok, so this would be the same trigger in an XML version:
Spoiler :
Code:
<Trigger>
    <ePlayer>2</ePlayer>
    <elements>
        <turn>
            <iTurn1>65</iTurn1>
            <iTurn2>None</iTurn2>
            <iInterval>1</iInterval>
            <iModulo>0</iModulo>
        </turn>
        <valid>
            <tCoords>None</tCoords>
            <bDomestic>False</bDomestic>
            <bForeign>False</bForeign>
            <bLand>True</bLand>
            <bWilderness>False</bWilderness>
            <bAdjacent>False</bAdjacent>
        </valid>
        <city>
            <iX>104</iX>
            <iY>45</iY>
            <name>"Qufu"</name>
            <iSize>2</iSize>
        <city>
    </elements>
</Trigger>
A lot more to type, but no Python involved. This example also shows all the settings involved.

And finally the "text-based" setup:
Spoiler :
Code:
BeginTrigger
        PlayerIndex=2
BeginElement
        Type=Condition_GameTurn
        GameTurn=65
EndElement
BeginElement
        Type=Condition_ValidMapTile
EndElement
BeginElement
        Type=Action_FoundCity
        Xcoord=104
        Ycoord=45
        CityName="Qufu"
EndElement
EndTrigger
Just as with the WBS you could omit a lot of settings if you can live with the default values. But its a lot of text to type, so you'd probably be copy-pasting triggers with all the default settings and then enter your own values on the appropriate lines.

I'm not done with it yet, but this is what the API looks like as of now:
Spoiler :
target
find

check
turn
year
waypoints
lost
valid
tech
era

city
culture
religions
buildings
name
units
garrison
XP
promotions
AI
terrain
erase
flip
discover
kill
degrade

Also, there would be no fiddling with Rhye's files because you'd put all your triggers in a clean module of your own. This is what a valid scenario module could look like:
Spoiler :
Code:
from PyScenario import Trigger
import Consts as con

Trigger(con.iChina).turn(65).valid().city(104, 45, "Qufu")
...and so on. You just add all the triggers you need below the import statements. What it does, is it loads all the triggers defined in such a module on setup (when the game itself loads) and only cycles through the triggers with valid conditions any time an "event" takes place in the game. (Like new game turn, city lost or tech acquired.) Very efficient. :king:

As an added bonus, the order of the triggers is arbitrary as is the order in which you type the elements (basically "conditions" and "actions") of a trigger. So this would also be valid:
PHP:
Trigger(con.iChina).valid().city(104, 45, "Qufu").turn(65)
User friendly, eh? :p
 
So as long as you only wanna make scenarios there would be no need to learn any programming. :D

Even if I plan on including support for custom Python scripts also, all in one package. As I envision this thing, it would be possible to define "triggers" for your scenario by any method available, and they would still work together. This because it would, for example, be useful to make events that contain text messages (or pop-ups) in XML - because there would be more space available for the actual string without cluttering down the entire document.

If I were ever to make a graphical interface for this scenario maker tool, the saved output would be of the text-based variety that looks sorta like the WBS file. So you could make a rough draft of your triggers within such an application (preferably within the actual game, like the World Builder) and edit the save file in Notepad for tweaks and corrections - optionally.

But now were getting ahead of yourselves! :p

Next thing is to make sure all triggers that have expired stay that way on save/load game. Otherwise they would all be initialized anew once the game is loaded, making events that should no longer apply trigger once again... So I'm not quite there yet even for a beta release. :p
 
If I were ever to make a graphical interface for this scenario maker tool, the saved output would be of the text-based variety that looks sorta like the WBS file. So you could make a rough draft of your triggers within such an application (preferably within the actual game, like the World Builder) and edit the save file in Notepad for tweaks and corrections - optionally.
Sorry for hijacking the thread, but I was looking at the code for the Mercenaries manager and realized I probably could just hijack the Mercenaries screen to fashion it into a Scenario Maker instead. You'd have to close it any time you wanna check up tile coordinates and the like, but any saved triggers would of course reappear once you reenter it.

So one pane would contain the available conditions and another would contain the actions. The main frame would list the already defined triggers, and by clicking on one you'd be able to access the conditions and actions again - and make edits. At the bottom would be buttons like "close", "save to file", "load from file", "clear" and "initiate".

The big issue right now would probably be how to record input from the user (like typed in values or names) but it shouldn't be impossible, at least. But this is still another project all to itself - I'm still working on getting the basic thing running. (I did solve the save/load issue, however. Luckily it turned out to be just as simple to fix as I imagined. So I'm nearing beta. :king:)
 
No offense to your heritage or nothin' Omega, but, Scotland isn't even a modern nation. Going to the ancient times it was first colonized by Ireland and was even named after the Irish tribe of Scots while the native Picts got their asses handed to them. Going forward to aprox. 1000 AD the kingdom of Scotland was already intermarried with the English line since before Edward I whom conquered Wales. Around the time of Brian Boru, Scotland was being regularly Raided by the Vikings. The Scots had to my knowledge three rebellions against the English, all of them put down with little enough effort, and it was with the end of the 2nd(?) that made Great Britain a United Kingdom.

'Sides Scotland is ON Great Britain, the English Civ just would not have the proper /being/ if you know what I mean? Like whoever played as Scotland would immediately move to take say Ireland.

Of course it is all up to Antaine on what he makes though, maybe you can make a convincing arguement as to why he should.
 
Top Bottom