Dune Wars Enhanced Patching

It is still redundant :D

1) There is a direct isBarbarian() check, so why such a long code just to check the same thing

2) Purpose of iCount which is totally unused?

3) Not sure what is the purpose of the getGroup check. Effectively 2 Dancers on the same plot, ungrouped will trigger, but if grouped will not trigger when whacking the same target... odd

4) CyTranslator().getText is meant to translate "TXT_KEY_XXX" text into the translated text files based on language.
Yet the input is already translated then what is the point, and it will always be displayed in English regardless of language of user.

5) I guess iEnemyUnitsCount is meant to count number of enemy units in the loser plot to decide whether to spawn the new unit in winner or loser plot.
Yet it is neither correct logic nor efficient.

Firstly, it is possible that units in the loser plot can be neutral units, or invisible ones.
So it is counting wrong things.

Secondly, there is a direct code to count visible defenders...
With that, you can easily decide which plot to use.

This plot check should also be used for the dance message, since currently the message will always spawn in the winner plot even if the winner moved to the loser plot after battle.
 
Cool, I knew that if I posted the code you would come and be picky:D.
I'll eventually try my best again.
 
2) Purpose of iCount which is totally unused?

3) Not sure what is the purpose of the getGroup check. Effectively 2 Dancers on the same plot, ungrouped will trigger, but if grouped will not trigger when whacking the same target... odd

Btw, this is part of the Kael code that I used, so you can take that criticism to him if you think yourself worthy:p

Firstly, it is possible that units in the loser plot can be neutral units, or invisible ones.
So it is counting wrong things.

Secondly, there is a direct code to count visible defenders...
With that, you can easily decide which plot to use.

This is actually useful.

Ah, its getNumVisibleEnemyDefenders (CyUnit pUnit). Excellent.
 
It doesn't matter who wrote the code.
Even if it is coded by professionals in Firaxis, I will still read through and understand the purpose of the code before I use it for my own usage.
Unless there are more codes below this portion, it is totally redundant.
 
It doesn't matter who wrote the code.
Even if it is coded by professionals in Firaxis, I will still read through and understand the purpose of the code before I use it for my own usage.
Unless there are more codes below this portion, it is totally redundant.

Thanks. Working with code professionally must be a pain.

getNumVisibleEnemyDefenders (CyUnit pUnit) does not count missiles and other units with combat str that can't defend?
 
Ignores all that cannot defend against the unit, including invisible ones without vision
 
Will this work? I can't test it right now, but I have the feeling I'm missing something. Btw, if you are so kind as to answer me this: what is the difference between is Attacking() and isMadeAttack()?

Spoiler :
Code:
                if pWinner.isHasPromotion(gc.getInfoTypeForString('PROMOTION_FACE_DANCER_FIGHTER')):
                        if not pPlayerLoser.isBarbarian():
                                if CyGame().getSorenRandNum(100, "Dance!") < 50:
                                        listProms = []
                                        for iProm in range(gc.getNumPromotionInfos()):
                                                if pLoser.isHasPromotion(iProm):
                                                        if pWinner.isPromotionValid(iProm):
                                                                if not pWinner.isHasPromotion(iProm):
                                                                        if not (iProm == gc.getInfoTypeForString('PROMOTION_HOMEGROUND') or iProm == gc.getInfoTypeForString('PROMOTION_HOMEGROUND2') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED1') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED2') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED3') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED4')):
                                                                                listProms.append(iProm)
                                        if len(listProms) > 0:
                                                iRnd = CyGame().getSorenRandNum(len(listProms), "Copy")
                                                pWinner.setHasPromotion(listProms[iRnd], True)
                                                if (pPlayer.isHuman()):
                                                        CyInterface().addMessage(pWinner.getOwner(),True,20,("Your unit has sucessfully managed to copy an opponent's promotion!"),"",1,gc.getPromotionInfo(listProms[iRnd]).getButton(),ColorTypes(8),pWinner.getX(),pWinner.getY(),True,True)
                        if eTeam.isHasTech(gc.getInfoTypeForString('TECH_GENETIC_MANIPULATION')):
                                if pWinner.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_MELEE'):
                                        if pLoser.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_MELEE'):
                                                if pWinner.baseCombatStr() < pLoser.baseCombatStr():
                                                        for i in range(pPlot2.getNumUnits()):
                                                                pUnit2 = pPlot2.getUnit(i)
                                                                if pPlot2.getNumVisibleEnemyDefenders(i) > 0:
                                                                        newUnit = pPlayer.initUnit(pLoser.getUnitType(), pWinner.getX(), pWinner.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
                                                                        newUnit.convert(pWinner)
                                                                        newUnit.finishMoves()
                                                                        if pPlayer.isHuman():
                                                                                CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)
                                                                else:
                                                                        newUnit = pPlayer.initUnit(pLoser.getUnitType(), pLoser.getX(), pLoser.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
                                                                        newUnit.convert(pWinner)
                                                                        newUnit.finishMoves()
                                                                        if (pPlayer.isHuman()):
                                                                                CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)
 
Duh, it should be like this. At least I'm a quick learner.

Spoiler :
Code:
                if pWinner.isHasPromotion(gc.getInfoTypeForString('PROMOTION_FACE_DANCER_FIGHTER')):
                        if not pLoser.isBarbarian():
                                if CyGame().getSorenRandNum(100, "Dance!") < 50:
                                        listProms = []
                                        for iProm in range(gc.getNumPromotionInfos()):
                                                if pLoser.isHasPromotion(iProm):
                                                        if pWinner.isPromotionValid(iProm):
                                                                if not pWinner.isHasPromotion(iProm):
                                                                        if not (iProm == gc.getInfoTypeForString('PROMOTION_HOMEGROUND') or iProm == gc.getInfoTypeForString('PROMOTION_HOMEGROUND2') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED1') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED2') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED3') or iProm == gc.getInfoTypeForString('PROMOTION_INSPIRED4')):
                                                                                listProms.append(iProm)
                                        if len(listProms) > 0:
                                                iRnd = CyGame().getSorenRandNum(len(listProms), "Copy")
                                                pWinner.setHasPromotion(listProms[iRnd], True)
                                                if pPlayer.isHuman():
                                                        CyInterface().addMessage(pWinner.getOwner(),True,20,("Your unit has sucessfully managed to copy an opponent's promotion!"),"",1,gc.getPromotionInfo(listProms[iRnd]).getButton(),ColorTypes(8),pWinner.getX(),pWinner.getY(),True,True)
                        if eTeam.isHasTech(gc.getInfoTypeForString('TECH_GENETIC_MANIPULATION')):
                                if pWinner.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_MELEE'):
                                        if pLoser.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_MELEE'):
                                                if pWinner.baseCombatStr() < pLoser.baseCombatStr():
                                                        if pPlot2.getNumVisibleEnemyDefenders(pWinner) > 1:
                                                                newUnit = pPlayer.initUnit(pLoser.getUnitType(), pWinner.getX(), pWinner.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
                                                                newUnit.convert(pWinner)
                                                                newUnit.finishMoves()
                                                                if pPlayer.isHuman():
                                                                        CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)
                                                        else:
                                                                newUnit = pPlayer.initUnit(pLoser.getUnitType(), pLoser.getX(), pLoser.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
                                                                newUnit.convert(pWinner)
                                                                newUnit.finishMoves()
                                                                if pPlayer.isHuman():
                                                                        CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)
 
1) Usually I will use canAcquirePromotion rather than isPromotionValid.
The difference is the former checks prereqs while the latter does not.
Using the latter, it is possible to copy Combat V without having Combat I to IV.

2) That whole chunk of hard coded promos can be simplified to this:
Code:
sType = gc.getPromotionInfo(iProm).getType()
if sType.find("PROMOTION_HOMEGROUND") > -1: continue
if sType.find("PROMOTION_INSPIRED") > -1: continue

The difference is that using this method, addition or deletion of further INSPIRED chain of promos can be done without modifying the python codes. You can add IV, V, X all you like.
Furthermore, using your method, if there is a typo, gc.getInfoTypeForString will return -1 and screw it.

3) Points 4 and 5 of previous post still the same.

4)
Code:
if pPlot2.getNumVisibleEnemyDefenders(pWinner) > 1:
                                                                [COLOR="Red"]newUnit = pPlayer.initUnit(pLoser.getUnitType(), pWinner.getX(), pWinner.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)[/COLOR]
                                                                newUnit.convert(pWinner)
                                                                newUnit.finishMoves()
                                                                if pPlayer.isHuman():
                                                                        CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)
                                                        else:
                                                                [COLOR="red"]newUnit = pPlayer.initUnit(pLoser.getUnitType(), pLoser.getX(), pLoser.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)[/COLOR]
                                                                newUnit.convert(pWinner)
                                                                newUnit.finishMoves()
                                                                if pPlayer.isHuman():
                                                                        CyInterface().addMessage(pWinner.getOwner(),false,20,("Your unit has shapeshifted into the defeated enemy!"),'',0,gc.getUnitInfo(newUnit.getUnitType()).getButton(),ColorTypes(8), newUnit.getX(), newUnit.getY(), True,True)

Besides the first line, everything else is the same, is there a need to copy twice under if and else?

isAttacking checks if the unit is currently attacking.
isAttacked checks if the unit has already made an attack, so it will be true for all units which have made an attack in the current turn.
 
1) Usually I will use canAcquirePromotion rather than isPromotionValid.
The difference is the former checks prereqs while the latter does not.
Using the latter, it is possible to copy Combat V without having Combat I to IV.

I know, i want it like that. Its a sci-fi fantasy mod...

2) That whole chunk of hard coded promos can be simplified to this:
Code:
sType = gc.getPromotionInfo(iProm).getType()
if sType.find("PROMOTION_HOMEGROUND") > -1: continue
if sType.find("PROMOTION_INSPIRED") > -1: continue

The difference is that using this method, addition or deletion of further INSPIRED chain of promos can be done without modifying the python codes. You can add IV, V, X all you like.
Furthermore, using your method, if there is a typo, gc.getInfoTypeForString will return -1 and screw it.

Nice to know!

3) Points 4 and 5 of previous post still the same.

What do you mean? I changed that.

4)Besides the first line, everything else is the same, is there a need to copy twice under if and else?
I can see a better way of doing it but it does not matter much; the spawning code, that did it matter. Thanks for the help.

isAttacking checks if the unit is currently attacking.
isAttacked checks if the unit has already made an attack, so it will be true for all units which have made an attack in the current turn.
Thanks.
 
4) cytranslator().gettext is meant to translate "txt_key_xxx" text into the translated text files based on language.
Yet the input is already translated then what is the point, and it will always be displayed in english regardless of language of user.


5)this plot check should also be used for the dance message, since currently the message will always spawn in the winner plot even if the winner moved to the loser plot after battle.

12345
 
That "12345" is because it is a requirement to type 5 letters to post a message lol
 
That "12345" is because it is a requirement to type 5 letters to post a message lol

Ah, yes. Still, you're sometimes cryptic. You probably have fun with that.

Thanks for the lesson again. I'll polish the code again some other time with your suggestions. Coding is not really that fun for a coding amateur like me, its the result I'm interested in.
For playability it is now working well.
 
It is good to see new coders who are willing to learn.

The first level of success is to ensure your code works in the general situation.

The second level is to ensure it works even in exceptional cases.
The iEnemyUnitsCount example is one that will fail here and give unwanted results.

Then finally you look at ways to improve efficiency.
Although computers nowadays can handle thousands of codes pretty fast, it is still good to improve it as much as possible to reduce lag in late game big maps.

Of course if I look at my earlier works one year ago, I can also spot inefficiencies here and there, but I can't be bothered either.
 
Going for step by step code polishing and learning.
Hopefully Platy or someone else can be so kind as to take a peak again:)

Does it look efficient or can it be improved?
Spoiler :
Code:
def GetCheckInfo(self, s):
		iVal = gc.getInfoTypeForString(s)
		if iVal == -1: BugUtil.debug("Failed to load %s", s)
		return iVal

def onCombatResult(self, argsList):
		'Combat Result'
		pWinner,pLoser = argsList
		playerX = PyPlayer(pWinner.getOwner())
		unitX = PyInfo.UnitInfo(pWinner.getUnitType())
		playerY = PyPlayer(pLoser.getOwner())
		unitY = PyInfo.UnitInfo(pLoser.getUnitType())
		pPlayer = gc.getPlayer(pWinner.getOwner())
		pPlayerLoser = gc.getPlayer(pLoser.getOwner())
	        pPlotLoser = pLoser.plot()
	        eTeam = gc.getTeam(pPlayer.getTeam())
	        iFremen = self.GetCheckInfo("CIVILIZATION_FREMEN")
	        iMelee = self.GetCheckInfo('UNITCOMBAT_MELEE')
                iGuard = self.GetCheckInfo('UNITCOMBAT_GUARDSMAN')
                
		#Start Fremen: DeathStill Water Gains from nearby combat
	        if (pLoser.getUnitCombatType() == iMelee or pLoser.getUnitCombatType() == iGuard):
		        if (pPlayer.getCivilizationType() == iFremen or pPlayerLoser.getCivilizationType() == iFremen):
                                CityArray = []
                                for x in xrange(9):
                                        for y in xrange(9):
                                                loopPlot = gc.getMap().plot(pLoser.getX() - 4 + x, pLoser.getY() - 4 + y)
                                                if not loopPlot.isNone():
                                                        if loopPlot.isCity():
                                                                pCity = loopPlot.getPlotCity()
                                                                #No need to check the owner; Fremen's UB is enough
                                                                if pCity.getNumRealBuilding(self.GetCheckInfo('BUILDING_DEATHSTILL')) > 0:
                                                                        CityArray.append(pCity)
                                if len(CityArray) > 0:
                                        iCity = gc.getGame().getSorenRandNum(len(CityArray), "City for Water")
                                        CityArray[iCity].changeFood(1)
                                        if pPlayer.isHuman():
                                                CyInterface().addMessage(pWinner.getOwner(), True, 20, CyTranslator().getText("TXT_KEY_MESSAGE_CITY_ADD_WATER_ENEMY",(CityArray[iCity].getName(), )), None, 2, pLoser.getButton(), ColorTypes(54), pLoser.getX(), pLoser.getY(), True, True)
		                        elif pPlayerLoser.isHuman():
                                                CyInterface().addMessage(pLoser.getOwner(), True, 20, CyTranslator().getText("TXT_KEY_MESSAGE_CITY_ADD_WATER_FREMEN",(CityArray[iCity].getName(), )), None, 2, pLoser.getButton(), ColorTypes(54), pLoser.getX(), pLoser.getY(), True, True)
                #End Fremen: DeathStill Water Gains from nearby combat
 
Top Bottom