[PYTHON] Action Buttons Utilities

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.
 
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 :(
 
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 []
 
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:
 
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?
 
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...
 
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?
 
Shqype said:
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.
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.
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?
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.
 
Aww man :(

Thanks for your answers.
 
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)?
 
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.
 
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 ?
 
theSeby said:
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 ?
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.
 
The Great Apple said:
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.
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.
 
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.
 
This is now somewhat obselete.

Edit: See the top for more info.
 
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.
 
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.
 
talchas said:
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.

I agree, I don't think either of us would have problems merging C++ mods, I'm just thinking about everyone else that could.
 
Top Bottom