Python - unit upgrading

The Great Apple

Big Cheese
Joined
Mar 24, 2002
Messages
3,361
Location
Oxford, England
Firstly, has anybody worked out a way to allow a unit a new upgrade based on a trigger? I can't see a way, but I may be missing something.

Also anybody managed to get CyUnit.doCommand(eCommand, int iData) to do anything? Ideally I'd like to be able to force an upgrade on a unit with a certain trigger - and this command seems the easiest way of doing it, but I can't seem to get it to do anything...
 
You can use CyUnit.doCommand to force a unit to upgrade. However it seems to only work inside that civs territory. If that's enough
CyUnit.doCommand(CommandTypes.COMMAND_UPGRADE, 0, 0) (I have no idea what the ints does) should work. If you want it to upgrade regardless of where it is you can use this:

Code:
plot = pUnit.plot()
owner = pUnit.getOwner()
xp = pUnit.getExperience()
dmg = pUnit.getDamage()
lvl = pUnit.getLevel()
promotions = []
iv = 0
for iii in range(gc.getNumPromotionInfos()):
[tab]if pUnit.isHasPromotion(iii):
[tab][tab]promotions.append(iii)
[tab][tab]iv += 1
pUnit2 = gc.getPlayer(owner).initUnit(gc.getInfoTypeForString('SOME_UNIT'), plot.getX(), plot.getY(), UnitAITypes.NO_UNITAI)
pUnit2.setExperience(xp, xp)
pUnit2.setDamage(dmg, False)
pUnit2.setLevel(lvl)
for iii in promotions:
[tab]if iii != -1: #Not sure if this is neccessary. -1 is NO_PROMOTION.
[tab][tab]pUnit2.setHasPromotion(iii, True)
pUnit.doCommand(CommandTypes.COMMAND_DELETE, 1, 1)

Note: the new unit will heal some of the damage (if any) when the turn changes because it hasn't moved. Should work to add a check if the unit have moved and if so use CyUnit.finishMoves() to make the new unit not heal, but I haven't tested that (yet).
 
snarko said:
... I have no idea what the ints does ...

What the ints are for depends on the context. In this case, I think the first int is used for the target unit class, because sometimes you hae more than one units classes to upgrade to. You should be able to determine the target unit class by using the function CyUnit.upgradeAvailable(eFromUnit, eToUnitClass, iCount).
 
Ah right, that's what the first int is, the number of the unittype you're upgrading to. As for the second one I don't think I ever figured that one out. If I did I certainly don't remember it.
 
If and how much of those ints are used, depends on the command. Some commands need none, some needs one. I don't know if there is any command which needs both ints.
 
I was never able to get doCommand() to work for forcing a unit to upgrade. I tried quite a few different variations on it. I have gotten doCommand() to work for other things.
 
Zurai said:
I was never able to get doCommand() to work for forcing a unit to upgrade. I tried quite a few different variations on it. I have gotten doCommand() to work for other things.

I'm ot sure if I uderstood you correct, but I think its not possible to "force" a unit to upgrade, as long as the upgrade is not available to the unit.

If you want to FORCE a unit, then it may be better to kill the old unit and reate a new one (with copying the pormotions and expereinces of cause.)
 
12monkeys said:
I'm ot sure if I uderstood you correct, but I think its not possible to "force" a unit to upgrade, as long as the upgrade is not available to the unit.

As far as I can tell, it's not possible to force a unit to upgrade using doCommand(COMMAND_UPGRADE) under ANY circumstances, including having the upgrade available.
 
Zurai said:
As far as I can tell, it's not possible to force a unit to upgrade using doCommand(COMMAND_UPGRADE) under ANY circumstances, including having the upgrade available.

It is possible. I have done it. If you can see the upgrade button it should work to upgrade the unit like that. I think this is what I used, for warriors:

pUnit.doCommand(COMMAND_UPGRADE, gc.getInfoTypeForString('UNIT_WARRIOR2'), 1) where warrior2 is a unit I had made that is a copy of warrior except immobile.

However your unit must be able to upgrade to the unit normally. If it's outside your territory, you don't have the tech required or anything else preventing an upgrade the click-a-button way it won't work.
 
snarko said:
pUnit.doCommand(COMMAND_UPGRADE, gc.getInfoTypeForString('UNIT_WARRIOR2'), 1) where warrior2 is a unit I had made that is a copy of warrior except immobile.

That sounds interesting. What are you working on?

We had CTP2 mods that implemented immobile militia units in cities.

On topic: as The Great Apple posted in the OP, and 12monkeys explained, CyUnit.doCommand(eCommand, int iData) takes two parameters. snarko, that second '0' you're using is redundant.

In the case where eCommand is COMMAND_UPGRADE, iData should be the UnitTypes to be upgraded to. Also,
you can use BOOL canDoCommand(CommandType eCommand, INT iData, BOOL bTestVisible) to test if the unit can perform the upgrade in the first place.
 
snarko said:
However your unit must be able to upgrade to the unit normally. If it's outside your territory, you don't have the tech required or anything else preventing an upgrade the click-a-button way it won't work.
Just out of interest, does the upgrade button show nomally? If so, isn't this a bit of a pain (it would seem this isn't a desirable upgrade)?
 
PeteT said:
That sounds interesting. What are you working on?

We had CTP2 mods that implemented immobile militia units in cities.

On topic: as The Great Apple posted in the OP, and 12monkeys explained, CyUnit.doCommand(eCommand, int iData) takes two parameters. snarko, that second '0' you're using is redundant.

In the case where eCommand is COMMAND_UPGRADE, iData should be the UnitTypes to be upgraded to. Also,
you can use BOOL canDoCommand(CommandType eCommand, INT iData, BOOL bTestVisible) to test if the unit can perform the upgrade in the first place.

I was working on a supply system where if you weren't connected to oil oil using units wouldn't be able to move. However it was scrapped because the AI wouldn't know how to handle it.

I'm pretty sure that CyUnit.doCommand takes three parameters. Unless it's changed with the latest patch. The API is wrong in some places, usually the site the link goes to have the correct info in that case.




The Great Apple said:
Just out of interest, does the upgrade button show nomally? If so, isn't this a bit of a pain (it would seem this isn't a desirable upgrade)?

I don't understand the questions.
 
The Great Apple said:
I meant, wouldn't you be able to press the upgrade button in normal play, and would this not cause weird things to happen?

If it would cause weird things or not depend on your code. When I tried to use it I made the upgrade require a disabled tech and gave that tech right before the code that upgraded the unit was run. Then removed the tech again right after. That way you never see the upgrade button but it still works to upgrade (assuming all other requirements are met).
 
When I tested it, the upgrade button was clearly visible and lit up (I was testing with warrior->axeman; I used the editor to give me mining and bronzeworking and to put copper under my starting city ie auto-connected), but the unit would not upgrade when the trigger was met.
 
Ok, just to make sure I tested it. This worked. It costed 85 gold, just like upgrading it normally would. But there's a huge problem with it. It seem to only work if the iron is connected to the capital AND the warrior is connected to the capital, which seems stupid to me because that's not required to normally upgrade it.

Code:
for i in range(gc.getPlayer(iPlayer).getNumUnits()):
[tab]pUnit = gc.getPlayer(iPlayer).getUnit(i)
[tab]pUnit.doCommand(CommandTypes.COMMAND_UPGRADE, gc.getInfoTypeForString('UNIT_AXEMAN'), 1)
 
Oh yeah, I also gave myself plenty of cash with the editor. I don't know what the problem was, but it was useless for my purposes anyway. I ended up using what someone suggested earlier (destroy and recreate).
 
Can I just ask about my first question again? At the moment I'm trying to get it so that when a unit gets a certain amount of experience it can upgrade to another unit, however I can't seem to figure out how to get this to work.

I suppose I could upgrade the unit into another one... and then upgrade that one into the third type - but I'd rather not as it would be really quite messy in the xml...
 
As far as I can tell, there's no way to dynamically add or remove potential upgrades. Also, doCommand seems to only function within the rules of the game - it's probably the function that the game calls when command buttons are pressed (like the unit upgrade buttons). I have yet to find any way to break the rules so to speak using doCommand.
 
Zurai said:
Oh yeah, I also gave myself plenty of cash with the editor. I don't know what the problem was, but it was useless for my purposes anyway. I ended up using what someone suggested earlier (destroy and recreate).

That's how I did it too since I specificly needed to upgrade units not in your own territory.


The Great Apple said:
Can I just ask about my first question again? At the moment I'm trying to get it so that when a unit gets a certain amount of experience it can upgrade to another unit, however I can't seem to figure out how to get this to work.

I suppose I could upgrade the unit into another one... and then upgrade that one into the third type - but I'd rather not as it would be really quite messy in the xml...

There problably is some other way to do it but I very much doubt it would become easier. Except for 'wait for the SDK' :p
 
Back
Top Bottom