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

[PYTHON] Action Buttons Utilities

Discussion in 'Civ4 - Mod Components' started by talchas, Jan 5, 2006.

  1. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    I designed this mod so that you can do whatever you want with it - I didn't include any restrictions like that for this reason. You could add a restriction in several ways:
    1. You could just set the moves on the unit to 0 when you click heal and then require 1+ moves left or it is disabled.
    2. You could allow only 1 healing per unit per turn by recording the fact that the heal ability has been used in the scriptData and then clearing this flag for all of a player's units in CvEventManager.onBeginPlayerTurn (or whatever its called). Then check this flag in the scriptData.
    3. Similar to 2, but instead just record the turn number each time it heals and only let it work if the turn number is different.
     
  2. Shqype

    Shqype Shqyptar

    Joined:
    Nov 15, 2005
    Messages:
    2,468
    Location:
    New York + Shqypni
    Thanks for the suggestion. I found this looking through Kael's python files:
    Code:
    pUnit.finishMoves()
    It should (by its name) finish a unit's moves ... the problem is where to put it. I've tried a couple of different things which all broke the code :(
     
  3. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    Use
    Code:
    def healUnit(healer):
        targetPlot = healer.plot()
        healer.finishMoves()
        ...
    
    and
    Code:
    def buttons(selectedUnit):
        heal.setEnabled(false)
        targetPlot=selectedUnit.plot()
        if(selectedUnit.getMoves()>0):
            for i in range(targetPlot.getNumUnits()):
    	    unit =targetPlot.getUnit(i)
                if(unit.getDamage()>0):
                    heal.setEnabled(true)
                    break
        if(gc.getUnitInfo(unit.getUnitType()).getType()=="UNIT_MEDIC"):
            return [heal]
        return []
    
     
  4. RED DIAMOND

    RED DIAMOND Prince

    Joined:
    Dec 24, 2005
    Messages:
    380
    OK Talchas, yes I am a fan:D This is really a great thing that you are doing here. You and The Great Apple are really nice people for helping us all out here. Thank you again.:goodjob:
     
  5. Shqype

    Shqype Shqyptar

    Joined:
    Nov 15, 2005
    Messages:
    2,468
    Location:
    New York + Shqypni
    I agree with you RED DIAMOND, by walking us through this code we get to borrow the confidence and expertise they possess and use it to learn the code and how it works ourselves :)

    Thanks for the fix talchas, but still buggy:
    Code:
    def healUnit(healer):
        targetPlot = healer.plot()
        healer.finishMoves()
        for i in range(targetPlot.getNumUnits()):
    	unit = targetPlot.getUnit(i)
    	if(gc.getUnitInfo(unit.getUnitType()).getType()=="UNIT_INJURED"):
    		unit.changeDamage(-10,gc.getGame().getActivePlayer())
    
    hurt = ActionButtons.ActionButton("Art/Interface/Buttons/Actions/SplitUnitGroup.dds",hurtUnit)
    heal = ActionButtons.ActionButton("Art/Interface/Buttons/Actions/CreateUnitGroup.dds",healUnit)
    
    def buttons(selectedUnit):
        heal.setEnabled(false)
        targetPlot=selectedUnit.plot()
        if(selectedUnit.getMoves()>0):
            for i in range(targetPlot.getNumUnits()):
    	    unit =targetPlot.getUnit(i)
                if(unit.getDamage()>0):
                    heal.setEnabled(true)
                    break
        if(gc.getUnitInfo(unit.getUnitType()).getType()=="UNIT_MEDIC"):
            return [heal]
        return []
    I tested out the code and came with up with the following results:
    -Medic never has the heal button available (not visible) on its first turn (when it has 2 moves left).
    -The icon ONLY appears when the medic has <2 turns.
    -Even with <2 turns remaining, the medic cannot heal an injured unit with <100 strength (full strength).

    So I went in and changed the if statement according to what I thought was the problem, an issue with the move amount. Just experimentation:
    Code:
    if(selectedUnit.getMoves()<2):
    Then I got new results:
    -The medic has the heal button appear every turn BEFORE it moves, once it moves then it disappears again.
    -Even if on its first turn with 2 moves, on a plot with the injured unit with <100 strength, the icon is still "grayed out" and the medic cannot heal the unit.

    Whoever thought this stuff could be so difficult?
     
  6. The Great Apple

    The Great Apple Big Cheese

    Joined:
    Mar 24, 2002
    Messages:
    3,361
    Location:
    Oxford, England
    You still have the bug where you are using "unit" to define two separate things.
    Code:
        if(gc.getUnitInfo(unit.getUnitType()).getType()=="UNIT_MEDIC"):
    should read:
    Code:
        if(gc.getUnitInfo(selectedUnit.getUnitType()).getType()=="UNIT_MEDIC"):
    The way it is at the moment if there is a unit that requires healing, that is the unit that would be checked to see if it was a medic, but not otherwise.

    As for the moving stuff - if you use
    Code:
    if (selectedUnit.canMove()):
    I think it should work out fine. There are some weird counter-intuative things that go on with movement...
     
  7. Shqype

    Shqype Shqyptar

    Joined:
    Nov 15, 2005
    Messages:
    2,468
    Location:
    New York + Shqypni
    Beautiful! Works perfectly! Thanks alot TGA :D

    The only thing left to do now is to restrict the "INJURED" unit from healing itself... I need to "delete" the Fortify until Healed button that all units have ... I want the medic to be the only source of health replenishment for this unit. If you know what python file this is handled in (the actions of the buttons), can you direct me to it? I believe it should be within my abilities to check for the unit type, and if it is INJURED, then to disable the self-heal button.

    talchas, do you have any tutorials or tips or sample code available for providing text for these newly created buttons? If not titles and descriptions like the normal game buttons, at least some sort of text that appears when the mouse pointer is over the button. That would improve the quality of the experience. Do you know in which python file such information would be set?
     
  8. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    The regular buttons are not handled at all in python. There are some definitions in various places in the XML, go see if deleting/disabling one is possible without a crash.
    You cannot do this with the normal help tooltips without the SDK (at least not that I've found). It definitely is not in the python though.

    However, you might be able to guess when the mouse pointer is over the correct button and activate the tooltip then.
     
  9. Shqype

    Shqype Shqyptar

    Joined:
    Nov 15, 2005
    Messages:
    2,468
    Location:
    New York + Shqypni
    Aww man :(

    Thanks for your answers.
     
  10. Thalassicus

    Thalassicus Bytes and Nibblers

    Joined:
    Nov 9, 2005
    Messages:
    11,057
    Location:
    Texas
    Is it possible to give units existing orders, and have it functional? For example, can you give a non-air domain unit the Air Strike ability without requiring a custom script to handle it (which the AI wouldn't know how to use)?
     
  11. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    You could certainly give it the button - loop through gc.getActionInfo(n)/getNumActionInfos and find which one is of the right type. Then use the same code used in CvMainInterface to add the normal buttons - its something like screen.addMultiListButton("BOTTOM something", ...). I'm not at a computer with Civ4 right now.
     
  12. theSeby

    theSeby Chieftain

    Joined:
    Feb 5, 2006
    Messages:
    19
    Location:
    Europa
    I've used this "tutorial" to add the steal-tech ability to the spy, and it's working.
    But now, how can I have Mouse-Over information, like for the other missions ?
     
  13. The Great Apple

    The Great Apple Big Cheese

    Joined:
    Mar 24, 2002
    Messages:
    3,361
    Location:
    Oxford, England
    Nope - we aren't able to add mouseover info yet. You possably could make a system which mimiced the current mouse-over info... but I don't know how hard it would be.
     
  14. RED DIAMOND

    RED DIAMOND Prince

    Joined:
    Dec 24, 2005
    Messages:
    380
    Hmm, that's of interest. How'd you do that?
     
  15. theSeby

    theSeby Chieftain

    Joined:
    Feb 5, 2006
    Messages:
    19
    Location:
    Europa
    Well... I'll look how I can do that (Have you any idea ?)

    >RED_DIAMOND
    I've "mixed" this add-a-button-tutorial and the TechConquest Mod.
    I'll probably release it this week.
     
  16. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    You could try to guess where the buttons are on the screen by keeping a counter recording the number of times addMultiListButton has been called and figuring out what each position corresponds to ingame in terms of x,y coordinates. Then you could override onUpdate in CvEventManager and check the mouse position each frame. If it has been over one of your buttons for a certain amount of time, draw your own tooltip. You could do that by using addImage or something for the background and addText for the text.

    Also, do remember that the AI will not use any of these buttons. If you want the AI to do stuff, wait for the SDK or override CvGameUtils.AI_update and try to work with that.
     
  17. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    This is now somewhat obselete.

    Edit: See the top for more info.
     
  18. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    Why is this now obsolete???

    EDIT: There might be people who don't know how to write C++ code or merge C++ code to effectively use your 2.0 version.
     
  19. talchas

    talchas Prince

    Joined:
    Jan 3, 2006
    Messages:
    428
    Well, I guess thats true, its just that the other version does every thing this one does and more, and does it without relying on C++'s lazy array bounds checking. I didn't think of having problems merging C++ mods.
     
  20. TheLopez

    TheLopez Deity

    Joined:
    Jan 16, 2006
    Messages:
    2,525
    Location:
    Oregon
    I agree, I don't think either of us would have problems merging C++ mods, I'm just thinking about everyone else that could.
     

Share This Page