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

[Map Script] PerfectWorld.py

Discussion in 'Civ4 - Map Scripts' started by cephalo, Aug 23, 2007.

  1. PieceOfMind

    PieceOfMind Drill IV Defender Retired Moderator

    Joined:
    Jan 15, 2006
    Messages:
    9,312
    Location:
    Australia
    :lol: Was it you cephalo who suggested that while waiting for the script to do its job, one can go and make a sandwich or a cuppa tea?

    Another thing I think you mentioned is that if the background music is still playing it probably means the game hasn't frozen.

    I can't remember if I've already said it buy great mapscript by the way! :goodjob:.
     
  2. Joecoolyo

    Joecoolyo 99% Lightspeed

    Joined:
    Apr 8, 2008
    Messages:
    9,908
    Location:
    茨城県
    Yah, I saw someone mention this mapscript in another thread, so I decided to check it out and it looks amazing! Though does it mean its frozen if the cursor never goes into its loading animation? If it just stays the regular cursor? Anyways, the first couple times I would load it when it stopped I would go to task manager and it would say BTS isn't responding, is that b/c of the slow loading or is there some other problem?
     
  3. PieceOfMind

    PieceOfMind Drill IV Defender Retired Moderator

    Joined:
    Jan 15, 2006
    Messages:
    9,312
    Location:
    Australia
    Task manager is not always that helpful. When a task says it is not responding it's not necessarily locked up. I was about to describe what it can mean, but I think it's literally what it says - not responding. That could mean it's just busy.

    Give it a go on a duel size map, and give it at least 5 minutes. If it still doesn't work then something might be wrong. Unless you have a very very old computer...
     
  4. Joecoolyo

    Joecoolyo 99% Lightspeed

    Joined:
    Apr 8, 2008
    Messages:
    9,908
    Location:
    茨城県
    I'll give it a go on duel, and my computer isn't that old, got it on '07, its a Dell with 2 Ghz of precessing speed and 2.00 GB of RAM
     
  5. Joecoolyo

    Joecoolyo 99% Lightspeed

    Joined:
    Apr 8, 2008
    Messages:
    9,908
    Location:
    茨城県
    Wow, it really was my impatience, the duel load took about 2 seconds, and the Huge map load (what I normally play) takes about 5 minutes... thanks for the help guys :D
     
  6. PieceOfMind

    PieceOfMind Drill IV Defender Retired Moderator

    Joined:
    Jan 15, 2006
    Messages:
    9,312
    Location:
    Australia
    Yes, the process of planet creation is not a quick one. Just be glad you can create planets to play on in five minutes and not millions of years. :p
     
  7. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    One other thing I noticed is that I always see the following in PythonErr.log:

    Code:
    Traceback (most recent call last):
    
      File "PerfectWorld_Original", line 4074, in addBonuses
    
      File "PerfectWorld_Original", line 2106, in AddBonuses
    
      File "PerfectWorld_Original", line 2293, in AssignBonusAreas
    
      File "PerfectWorld_Original", line 2507, in CalculateAreaSuitability
    
      File "PerfectWorld_Original", line 2483, in GetSameClassTypeCountInArea
    
    TypeError: 'int' object is not callable
    ERR: Python function addBonuses failed, module PerfectWorld
    
    I don't know if this is significant or not. I'm on a mac, btw.
     
  8. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    What is "PerfectWorld_Original"? The line numbers don't match up in my version. If someone copied text from there to make a modified PerfectWorld, it's possible that the tabs don't line up, causing Python to interpret things wrong.
     
  9. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    It's the original version; I just renamed it to keep it safe from my experimentation. Maybe I goofed, I don't think so, though; I'll check again.

    When you say they don't line up, do you mean you see different line numbers when you run it, or do you not see this at all? If I download the version linked at the top of the thread, line 2507 is

    Code:
    sameClassTypesInArea = self.GetSameClassTypeCountInArea(area,eBonus)
    This seems to agree with the errors messages I'm seeing. Line 2483 is

    Code:
    uRange = classInfo.getUniqueRange()
    I don't know enough about python to know if this can generate that message.
     
  10. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    This is line 2471 for me. The context is...
    Code:
            classInfo = gc.getBonusClassInfo(eClass)
            if classInfo == None:
                return 0
            uRange = classInfo.getUniqueRange() (line 2471)
    
    So classInfo should be a valid bonus class and if not, the function should end. Keep in mind that indentation can completely change the meaning of Python code. Significant white space is one of the really annoying things about Python. If you use a non-Python IDE you can really create some confusion if spaces look like a tab etc.
     
  11. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    I'm not sure what to say, when I download a fresh copy of PerfectWorld.py, the uRange = classInfo.getUniqueRange() is line 2483. Are you sure you're looking at the same version of the file that's posted there? I don't see what could be causing the difference, I'm looking at a freshly downloaded file.

    Edit: The API reference here lists getUniqueRange as an attribute not a method. Should this line read

    Code:
    uRange = classInfo.getUniqueRange
    instead of

    Code:
    uRange = classInfo.getUniqueRange()
    ??? That seems like it could explain this message. But 'getUniqueRange' seems like a funny name for an attribute, maybe the API reference is wrong?
     
  12. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    Ok, I was using a messed up version I had at work when I was looking at the line numbers. The line numbers you mentioned are the correct ones. However, after coming home and trying a fresh copy with the game, I did not get the error message in my log. You mentioned that you are using a Mac, and in fact the Mac version and Windows version of CivIV use different versions of python. A while back I had some Mac issues because I was doing things only valid in Python 2.4, while the Mac version uses Python 2.3. I thought I had stripped out all the 2.4isms but there may be more.

    Are you still getting the message when trying a fresh copy with the game? I wanna make sure it's not an indentation issue before I start looking at Mac specific stuff.
     
  13. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    Okay, so I did what you asked. I moved any versions of PerfectWorld.py out of the PublicMaps folder. Then I started Civ and went to the custom game screen just to make sure that PerfectWorld was not available as an option. It wasn't. So then I unzipped a clean version of PerfectWorld.py and put it in the PublicMaps folder. Restarted Civ and started a game with PW. Got the error I reported above.

    So then I went into PW and deleted the parentheses at the end of line 2483 like I suggested above and reran civ. This time I got this error message:

    Code:
    Traceback (most recent call last):
    
      File "PerfectWorld", line 4074, in addBonuses
    
      File "PerfectWorld", line 2112, in AddBonuses
    
      File "PerfectWorld", line 2203, in AddBonusType
    
      File "PerfectWorld", line 2331, in CanPlaceBonusAt
    
    TypeError: 'int' object is not callable
    ERR: Python function addBonuses failed, module PerfectWorld
    
    Same message, different line. That line also has " uRange = classInfo.getUniqueRange()". So I deleted the parentheses there and at the one other location where that appears. Ran Civ again ... this time the error is
    Code:
    Traceback (most recent call last):
    
      File "PerfectWorld", line 4074, in addBonuses
    
      File "PerfectWorld", line 2112, in AddBonuses
    
      File "PerfectWorld", line 2203, in AddBonusType
    
      File "PerfectWorld", line 2344, in CanPlaceBonusAt
    
    TypeError: bad operand type for unary -
    ERR: Python function addBonuses failed, module PerfectWorld
    
    So my changes are making the original errors disappear, but are obviously not fixing the situation. Let me know if you want me to do some more testing/investigation.
     
  14. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    The function in question should just be a regular function call similar to others in the info classes. It basically just returns the appropriate XML value. I would think there would be some preceding error. Do you have popups turned on in your ini file? I wonder if you might see a popup that happens before this error.

    After getting another clean copy, put this line right before the one in question:

    print "classInfo = %d" % (classInfo) :EDIT no don't do this
    Do this:
    print "classInfo ="
    print classInfo

    Otherwise print requires a specific type.

    I wonder what value is in there. I also wonder if my testing of 'None' is failing. Maybe the Mac version returns a zero instead of 'None' or something like that. Look in your logs for the PythonDbg.log file, you should be able to find your print statement (uh... mixed in with some other junk, use the find feature in your text editor)
     
  15. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    Okay, I didn't do exactly what you said, but I think I found/fixed the problem. What I'm not sure of is why you don't get the same error! Maybe more recent versions of python are more forgiving or more flexible in how you can access attributes?

    Anyway, I'll just cut to the chase. There are three uses of getUniqueRange in PW. According to the API reference, getUniqueRange is an attribute of CvBonusClassInfo but a method of CvBonusInfo. So what works for me is

    Code:
    classInfo.getUniqueRange
    but

    Code:
    bonusInfo.getUniqueRange()
    Interestingly, I was beginning to think from the games I've played that the maps were relatively resource poor (not for all resources, though). I wonder if that will change.

    Edit: Did the API change in Warlords/BTS? I'm testing this in Vanilla Civ, maybe that's the difference?

    More info under the spoiler tag.

    Spoiler :

    I modified the code as follows in the three places that getUniqueRange appears:

    Code:
                print "(Added by dr_s at 2331) classInfo = "
                print classInfo
                iRange = classInfo.getUniqueRange
                print "(Added by  dr_s) iRange = "
                print iRange
    
    Code:
            print "(Added by dr_s at 2343) bonusInfo = "
            print bonusInfo
            iRange = bonusInfo.getUniqueRange()
            print "(Added by dr_s) iRange = "
            print iRange
    
    Code:
            print "(Added by dr_s at 2483) classInfo = "
            print classInfo
            uRange = classInfo.getUniqueRange
            print "(Added by dr_s) uRange = "
            print uRange
    
    The output from this is (each repeated many times, of course):

    Code:
    (Added by dr_s at 2331) classInfo = 
    <CvPythonExtensions.CvBonusClassInfo object at 0x18325148>
    (Added by  dr_s) iRange = 
    4
    
    Code:
    (Added by dr_s at 2343) bonusInfo = 
    <CvPythonExtensions.CvBonusInfo object at 0x183250d8>
    (Added by dr_s) iRange = 
    7
    
    Code:
    (Added by dr_s at 2483) classInfo = 
    <CvPythonExtensions.CvBonusClassInfo object at 0x18325068>
    (Added by dr_s) uRange = 
    5
    
    With this code I get no errors in PythonErr.log and what seem like reasonable values for everything in PythonDbg.log.


     
  16. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    That is very strange. I don't know what's going on with that. I never used the API reference you mentioned, I used the SDK in Visual Studio to find calling parameters and such. Generally, the methods exposed to python use the same format as their counterparts in the SDK.
    Code:
    int CvBonusClassInfo::getUniqueRange() const
    {
    	return m_iUniqueRange; 
    }
    
    
    I'm surprised that you are getting reasonable values for your uRange variable. In the CIV4BonusClassInfos.xml file, the iUnique values are either 0,4,5 or 8.

    Also, that error you are getting is very strange. Clearly, the classInfo var is holding an object, yet you get an error saying you can't call a method on an 'int'. But it's not an int.... EDIT, oh wait, I get it now. It's already an int. Hmmm...

    When I get home I'm going to make sure I'm getting the 0,4,5 or 8 on these values, and maybe try it without the parenthesis but I would expect an error. I haven't seen anything in Civ modding that uses attributes that way.
     
  17. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    No, but if the API reference is right, then classInfo.getUniqueRange is an int, so classInfo.getUniqueRange() would return that error. (At least I think so, based on my googling.)

    My hypothesis is that getUniqueRange is supposed to be a method, based on its name, for both CivBonusInfo and CivBonusClassInfo, but it's not, at least not in the Mac version of Civ (or maybe in Civ Vanilla).

    On an unrelated matter, I sometimes see very food-poor starting locations (see attached screenshot) and I wonder if you have a comment about that. (BTW, there isn't any nearby food just out of range of the screenshot.)
     

    Attached Files:

  18. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    Ugh, that's an annoying version difference. I wonder what else is out there that is simply not working at all for Mac people. If addBonus fails it will resort to the default method, which will result in a very resource poor map since PW likes alot of trees. My bonus placer will place food bonuses over trees while the default one will not.

    Actually it is very related. :) If you can get it working, as you have hopefully done, this problem should go away. Check to make sure you are getting the expected iUnique range values from the XML file using that attribute.

    However, I'm not sure what I ought to do about this... I don't have a Mac for testing purposes.
     
  19. cephalo

    cephalo Chieftain

    Joined:
    Jul 26, 2007
    Messages:
    2,055
    Location:
    Missouri, USA
    Ok, I think I have determined it is a Vanilla issue. I googled some old discussions regarding some confusion with that function, and also the BtS version of the API reference you mentioned lists it as a method, while in vanilla it is an attribute as you said. So, they must have changed it. I didn't start modding until BtS came out, so that's why I never noticed it.

    You definately want my version of the bonus placer, not only will it deal with the forests better, it will also put resources on the smaller islands while the default placer will not.

    Thanks for pointing out that bug! It's good to know. :goodjob:
     
  20. dr_s

    dr_s Chieftain

    Joined:
    Dec 27, 2006
    Messages:
    536
    Glad you figured it out. Is there a workaround, so that a single version will work on both Vanilla and BTS?

    BTW, I'm pretty sure the start I posted above was made with the fixed code. But even if it was not, here are two more low-food starts that I've seen. These were definitely made with a working script.
     

    Attached Files:

Share This Page