Platyping's Promotions and Traits

yes but xp is calculated overall...

the levels are needed for compatibility with normal promotions, I can't really explain why though. I have made a breakthrough however that allows for method B to work, a simple calculation in CvUnit to decide what tier the unit is advancing through, for use in the codes :D simple!
 
although, it presumes a unit can only pass through one tier at a time... which isn't the case... tiers can have independent trees;

tier I, tier II, tier III are in a chain
tier 1, tier 2, tier 3 are in another chain

if the unit can acquire both tier trees he can be in BOTH tier I and tier 3 at the same time... hmm rethink on this function
 
Very simple.
When a unit gains a tier promotion, is it supposed to increase threshold of normal promotion or does not affect.

So when a unit of lvl 3 reaches 17 xp, if it chooses a normal promotion, it should now need to reach 26 xp for next promotion, xp required has increased from 7 to 9.
If it chooses a tier promotion instead, is it supposed to require 7 or 9 xp for next promotion?
 
doesn't increase the normal promotion threshold

so normally;

promotions at

2
5
10
etc

if a tier promotion xp is reached (which the formula is now ammended to [xp for previous level + xp for this tier]) then it doesn't increase the level and therefore doesn't increase the cost of a normal promotion, what it does do is it resets the xp back to what it was just after the last normal promotion was picked + the extra xp over the last tier promotion for example

(for these purposes all tiers cost 2 xp)

unit has picked two normal promotions in the past and so is at level 3, and at 10 xp. it continues gaining xp until it has 15 xp. It could have gotten a promotion at 12xp for the tier (10xp + 2), but waited. it chooses the tier promotion and it's experience is set back to 10 + (15-12) = 13. it can choose another tier promotion and does so (the level hasn't changed so the new promotion is still required at 12 and the next normal promotion at 17) and it's experience is now at 11xp.

now it saves xp up to 17, where it takes the normal promotion and the level increases to 4. the next tier promotion is available at 19. at xp 19 it picks the tier and the xp is set back to 17 again.

hopefully you can understand all of that :p
 
What needs to be done is get the threshold for previous lvl which means 10.
When Xp reaches this value + tier xp, make it possible to promote tier promotions but not normal ones.
If tier promotion is selected, reduce xp by tier xp.
If chose not to do tier promotion, when xp reaches the real threshold 17, makes normal promotions available too.
If normal promotion selected, increase lvl by 1.
 
exactly, and I am really close! All I need to do is work out how I can calculate the currently available tiers for a unit... which is proving to be very difficult... any ideas?

some background

CvPromotionInfo has method called getTierType()

CvPromotionTierInfo has methods for required tech and tier.

I need a function to give me ALL the tiers that the unit can acquire promotions from...
 
Loop through all promotions and simply use canacquirepromotion to sort out what are the promotions available for that unit at that point of time given its current promotions and technologies.
If xp >= 12 but less than 17, ignore all the normal promotions, which means what's left are the tier ones.
If xp >= 17 include the normal ones
 
that would be nice and simple, except for one thing...

tiers are not all the same cost!

for Babylon 5 mod at least tier I is 4xp tier II is 6xp tier III 8xp and so on!

so what I need is to evaluate every separate available tier to see if it reaches the xp requirements for itself. if at least one of the available tiers OR a normal promotion can be acquired then code moves on and future methods in the chain then filter out individually which promotions can be acquired at this xp and which can't. Normally the code checks if any promotions are available and is the xp right then filters out which promotions can actually be chosen later

so I need a function to yeild all the tiers that the unit has available to it to use in this code:

Code:
void CvUnit::testPromotionReady()
{
	//EnhancedPromotions - Start
	bool bXpMet = getExperience() >= experienceNeeded();
	[B]std::vector <int> tiers = getCurrentTiersOnUnit();[/B]
	for (std::vector <int>::size_type i = 0; i < tiers.size(); i++)
	{
		bXpMet = bXpMet || getExperience() >= experienceNeeded(tiers.at(i));
	}
	setPromotionReady((bXpMet) && canAcquirePromotionAny());
	//EnhancedPromotions - End
}
 
Loop through all promotions it can aquire and get the minimum tier lvl.
So long has it is eligible to earn a tier 1 promotion in 1 tree, it should be set to promotion ready at 12, regardless of what other tiers the other trees are at
 
I had a dumb moment and figured it out on the way to the shop, all I need to do is say if a promotion can be acquired, what is its tier and add that to the list of tiers to check, as if a promotion can be acquired the tier is not finished and the previous tier is!

the problem is if there are two tier trees both available to the unit, if one tree is at tier I (and so at 4xp per promotion) and the other is at tier IV (and so at 10xp per promotion) then both need to be checked to see if either can be acquired! otherwise weird things happen. Anyway thanks for your help. Everything should be plain sailing for now!

Code:
void CvUnit::testPromotionReady()
{
	//EnhancedPromotions - Start
	bool bXpMet = getExperience() >= experienceNeeded();
	std::vector <int> tiers = getCurrentTiersOnUnit();
	for (std::vector <int>::size_type i = 0; i < tiers.size(); i++)
	{
		bXpMet = bXpMet || getExperience() >= experienceNeeded(tiers.at(i));
	}
	setPromotionReady((bXpMet) && canAcquirePromotionAny());
	//EnhancedPromotions - End
}

//EnhancedPromotions - Start
std::vector <int> CvUnit::getCurrentTiersOnUnit()
{
	std::vector <int> tiers;
	for (int i = 0; i < GC.getNumPromotionInfos(); i++)
	{
		if (canAcquirePromotion((PromotionTypes) i) && !std::find(tiers.begin(), tiers.end(), GC.getPromotionInfo((PromotionTypes) i).getTierType()))
		{
			tiers.push_back(GC.getPromotionInfo((PromotionTypes) i).getTierType())
		}
	}
	return tiers;
}
//EnhancedPromotions - End
 
As I said, what you need is just the min tier lvl so you don't have to use a for loop and check each different tier.
If one is at tier I and the other is tier iv, obviously the unit should be promotion ready when it reached xp threshold for tier I.
Why will you still want to test if it has reached threshold for tier iv to decide it should be ready for promotion
 
because, why should they both be ready xp wise at the same time?

if one of the accessable tiers needs 2xp
and the other requires 5

then their first meeting without bugs will be at 10xp. BUT there could have been an acquisition at 5xp aswell!! but it isn't a multiple of 2 so it doesn't fit...

all available tiers must be checked to see which ones can be done, maybe all can be done, or just one can be done...
 
According to how you describe the system earlier.
If current xp is at 10,
At 12, I should be able to select a tier I promotion if there is any.
At 14, tier ii if any.
At 17, normal if any.

If that is the case, if one is at tier I and the other ii, I will just check for tier I rather than check for both
 
wait you're right... I was thinking about you needing the exact amount of xp :ack:

still even with that ideology, how do you know which tier is the cheapest without going through :p
a tier isn't given a number like I II III a tier is this:

Code:
		<PromotionTierInfo>
	        	<Type>PROMOTION_TIER_TRAINED</Type>
	        	<Description>TXT_KEY_PROMOTION_TIER_TRAINED_DESC</Description>
	      		<PrereqTech>TECH_B5_EARLY_SPACE_CRAFT</PrereqTech>
	      		<PrereqTier>NONE</PrereqTier>
			<iCost>4</iCost>
			<Button>Art/Interface/Buttons/Promotions/TierI_Button.dds</Button>
		</PromotionTierInfo>

so how do you know which one is the lowest xp available? you still have to go through all of them :lol: because the costs don't have to increase, they could decrease! or fluctuate!

But I see what you mean, I don't have to check if the xp is available for them, thanks!
 
Look at your promotion ready codes.
The getcurrenttiers code is looping through all available promotions and appending the tier to a list.
Then you still do a for loop and compare each tier to the xp to decide if promotion ready.
Which means 2 loops done.

Instead of this, I will just use a getmintier function and loop through available promotions just like what getcurrentier is doing.
However, if I found tier I, I can break the loop
Also, it will just return 1 value, the minimum.
Then next step, I will just compare this min tier to decide promotion ready and done.

If same tier lvl of different trees may have different cost, then just change to min cost.
Why is a python modder teaching a SDK modder how to mod SDK :D
 
you're not you're just advising me on the design for the feature :lol:, ok how to I find the min cost tier? I can't hard code any names or it removes usablility. I have to cycle ONCE and find the lowest cost, I cannot break when I find the lowest cost because I don't know that it is the lowest cost! Hence here is my final solution

Code:
void CvUnit::testPromotionReady()
{
	//EnhancedPromotions - Start
	setPromotionReady((getExperience() >= experienceNeeded(getLowestTierOnUnit()) ||
					   getExperience() >= experienceNeeded()) && canAcquirePromotionAny());
	//EnhancedPromotions - End
}

//EnhancedPromotions - Start
int CvUnit::getLowestTierOnUnit()
{
	int cost;
	int tier;
	for (int i = 0; i < GC.getNumPromotionInfos(); i++)
	{
		if (canAcquirePromotion((PromotionTypes) i) && GC.getPromotionInfo((PromotionTypes) i).getTierType() != NO_TIER)
		{
			if (GC.getPromotionTierInfo((PromotionTierTypes) GC.getPromotionInfo((PromotionTypes) i).getTierType()).getCost() < cost)
			{
				cost = GC.getPromotionTierInfo((PromotionTierTypes) GC.getPromotionInfo((PromotionTypes) i).getTierType()).getCost();
				tier = GC.getPromotionInfo((PromotionTypes) i).getTierType();
			}
		}
	}
	return tier;
}

That is the only way of completing this :p you can't break the loop or risk missing a cheaper tier. There is no variable in global defines or somewhere to dictate the lowest xp cost present in the tiers, therefore I have to look through everyone. And if I was to loops through the tiers instead of promotions, I would find the cheapest but I wouldn't know if it was available! A unit doesn't store in it's class what tiers it is doing...

(also I was way ahead of you, I even renamed the name of the function before you posted :p)
 
experienceNeeded = level * exp_for_tier if isTierPromotion() else level * level + 1

This formula is still wrong.
I won't even need to adjust the formula.

The min formula should just return the min cost and not the min tier.
Why return tier when what you want to know is the cost, since you said the cost of each tier I can be different for different tier tree.

All I need to know is what is the min cost.
Then simply take the basic BTS getExperienceNeeded formula for the PREVIOUS level, and add the cost.
If current XP >= min((XP needed for current lvl + min cost), XP needed for next level), it is promotion ready.

However, if cost is same for all tier I for all tier trees, then I can break the loop once one of the promotions is tier I.
 
the cost of each tier is defined in the tier, however. in a tree of tiers, tiers that hold the base tier might have two different costs, so the base of tree A might need 2 xp and the base of tree B might need 3xp but they are two separate tiers!. The cost for a tier though, never varies. It is what it is in the xml. A tier can only be used in one tier tree.

and as the Tiers are not named Tier_I they are named anything you want, you can't tell if the tier you are looping through is a tier I or not! And in fact, a Tier I promotion might cost more than a Tier II. So the current system IS required, yes, I could pass in the cost instead of the tier. But for the moment that is how I want to do it, just in case I add more stuff to the tiers, to the extent that a simple int cannot be used to calculate the xp and I need the tier itself, to get al sorts or modifiers etc.

python defines looks like this:

Code:
	def getExperienceNeeded(self, argsList):
		# use this function to set how much experience a unit needs
		iLevel, iOwner, iTier = argsList
		
		iExperienceNeeded = 0

		# regular epic game experience
		# EnhancedPromotions - Start
		if iTier == PromotionTierTypes.NO_TIER:
                        iExperienceNeeded = iLevel * iLevel + 1
                else:
                        iExperienceNeeded = (iLevel - 1) * (iLevel - 1) + ((iLevel - 1) != 0) + gc.getPromotionTierInfo(iTier).getCost()
		# EnhancedPromtoions - End

		iModifier = gc.getPlayer(iOwner).getLevelExperienceModifier()
		if (0 != iModifier):
			iExperienceNeeded += (iExperienceNeeded * iModifier + 99) / 100
			
		return iExperienceNeeded
 
Does it make sense that you are doing this?

1) getLowestTierOnUnit is checking the cost of each tier promotion.
2) Then it returns the tier of the promotion with the lowest cost.
3) Then you input this tier into getExperienceNeeded function
4) So that you can get the cost of this tier promotion.

So you already found what you wanted in step 1, yet you rather get this tier value and input into step 2 and 3 so that in step 4, you get the value that you already obtained in step 1?
 
well, I could but what if I wanted to add more modifiers to the code, then I would need to pass more stuff in, alternatively I access the tier itself, it's easier that way. Just in case I add new things
 
Top Bottom