Announcement

Collapse
No announcement yet.

Enum madness

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

  • Enum madness

    I knew zero Python before I started modding a week ago, however I am a Java/C/C++/Perl programmer by day. I'm having a little wierdness with enumerations in my mod code.

    Problem #1) When I try to pass the result of a method like getTeam() as a paramter to a function that wants a TeamType in that position I will sometimes get an argument error saying that "int" does not match "enum TeamTypes." As a result I have to cast it to (TeamTypes).

    I didn't expect Python to require explicit casting and I don't see the existing Assets code casting anything anywhere even in places where a function returns an int and is passed directly to a call that wants an enum. So I must be doing something wrong.

    Example of inconsistency:

    gc.getTeam(gc.getGame().getActiveTeam()).isAtWar(g c.getPlayer(i).getTeam())

    plot.calculateNatureYield( YieldTypes.YIELD_COMMERCE, (TeamTypes)(gc.getGame().getActiveTeam()), True )

    Both lines run flawlessly, but the 2nd line runs only if I cast the team like I show. Both isAtWar and calculateNatureYield expect a TeamType, and both getTeam and getActiveTeam return an INT. They should behave the same, but they don't.


    Problem #2) I can use YieldTypes.YIELD_FOOD as a constant and pass that into methods expecting a YieldType paramater. But when I try to use ImprovementTypes.IMPROVEMENT_FARM I get an error saying that ImprovementTypes has no attribute IMPROVEMENT_FARM. I haven't actually gotten any of the ImprovementTypes to work except NO_IMPROVEMENT and some other enums don't work either (FeatureTypes I think). Is the documentation wrong here, or am I in error here too?

    Example:
    x = gc.getInfoTypeForString('IMPROVEMENT_FARM')
    y = ImprovementTypes.NO_IMPROVEMENT
    z = ImprovementTypes.IMPROVEMENT_FARM

    Crashes on the 3rd line (z). x and y work fine...


    Thanks for any help you assorted Python gurus.

  • #2
    Some enums are generated dynamically from the XML - like Improvements. The enum only starts with one value: NO_IMPROVEMENT. Which is why that one works.

    There's a helper function in CvUtil you can use to get around this.
    Code:
    CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_WARRIOR')
    This line will get the Unit ID for the Warrior. If you want an Improvement instead change it to getImprovement Info and getNumImprovementInfos and of course the tag of the improvement you want.

    Comment


    • #3
      Originally posted by Trip

      Code:
      CvUtil.findInfoTypeNum(gc.getUnitInfo, gc.getNumUnitInfos(), 'UNIT_WARRIOR')
      Wow... now that feels quite unpythonic. Why not simply a dictionary-like object?

      Code:
        ImprovementTypes['IMPROVEMENT_FARM']

      Comment


      • #4
        That function in CvUtil is essentially a wrapper for a function in C++ exposed through Boost.

        Comment


        • #5
          Yah. thought so. When i did wrapping of c into python with swig typing can be a problem sometimes.

          Comment


          • #6
            Trip: Thanks for the help with #2, that explanation makes sense.

            As for #1, does anyone have any insight as to why those two method calls behave differently? Is it normal to have to cast ints to enums?

            Comment


            • #7
              Originally posted by Skoll
              Is it normal to have to cast ints to enums?
              If you mean python itself the answer is no. Python is a dynamically strong typed language (facilitating duck-typing from that...)

              I think what really is missing in the CIV Python scripts are higher level wrappers to get around those unnecessary long function calls. For example a convenience object that collects all enums into a simple to query dict like object (holding that enum-typed boost thingies) structure would be nice.

              Comment

              Working...
              X