General DLL programming questions

New question now. I've been trying again to get the DLL to compile in Visual Studio 2012 Express, and I think the issue is with the environment variables and directories. They are controlled in 2012 in this window

attachment.php


But I can't find where they are in VC++ 2008. I figure that if I change all of the directories in 2012 to what they are in 2008 that it may compile. Does someone know where that data is kept in the 2008 version of Visual C++?

So I've been working on this some more and here is what I've changed the variables to respectively.

Code:
$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);
$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;C:\Users\*Name Removed*\Documents\SDK Workspace\WindowsSDK\include;
..\Sources;$(ReferencePath)
$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;C:\Users\*Name Removed*\Documents\SDK Workspace\WindowsSDK\lib;
$(WindowsSDK_MetadataPath)
$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\mfcm;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src;
$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;C:\Users\*Name Removed*\Documents\SDK Workspace\WindowsSDK\include;$(MSBuildToolsPath32);$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;

But it still gives me some errors (though not as many as before). Does anyone else have an idea of what else would need to be changed to get it to compile in VS2012?
 
I just want to make sure I'm doing this right, is this code the right way to make withdrawal multiplicative?
PHP:
void CvUnit::changeExtraWithdrawal(int iChange)															
{
	//ls612: Withdrawal is now multiplicative, so there is dimishing returns
	m_iExtraWithdrawal += ((iChange * std::max(0,100 - m_iExtraWithdrawal)) / 100);
	FAssert(getExtraWithdrawal() >= 0);
}
 
The two things it would not make multiplicative in such a structure would be the base amount of withdrawal and any amounts coming in from generals.

The math seems sound but perhaps the wrong approach. Additionally, it's something that would kinda mess with players heads: "I just gave them +25% withdrawal... why did it only end up being +22%?"

I'm thinking if you want this kind of diminishing return effect, then act on the total itself: CvUnit::withdrawalProbability. Then create a mathematical process that preserves the first 50%, then any value over that continue to divide by half per 50 cumulative. Thus 100 = 75, 150 = 87(.5), 200 = 93(.75), 250 = 96(.975), 300 = 98(.5375) etc...

Off the top of my head I'm not sure how to best encapsulate that in c++ math but it would be more effective at creating the effect you're looking for. I'd thought about what you said in the other thread and was wondering if you'd be seeking to go about it the above noted way and so I'd been thinking of this some... Additionally, this way it'd be much easier to make an IF statement that returns the current normal value (I think one is already even there!) if Pursuit is in use and instead returns your method if it is not.
 
I'm thinking if you want this kind of diminishing return effect, then act on the total itself: CvUnit::withdrawalProbability. Then create a mathematical process that preserves the first 50%, then any value over that continue to divide by half per 50 cumulative. Thus 100 = 75, 150 = 87(.5), 200 = 93(.75), 250 = 96(.975), 300 = 98(.5375) etc...

That sounds better, thanks. Also, we can use hover text to give the exact value to players, thus eliminating the need for them to mentally do any math in this regard.
 
The Combat Help hover will do the math for them already. But it'll take some tricksy stuff in the promo help section if you want to include it in there somehow. Particularly with the display coming up a bit different on a promotion you're looking to select vs one that you already have (that may be compiled into others).

But some kind of explanation should go somewhere as to how this works. The Unit Help hover popup info will also express the final value that comes from withdrawalProbability as well so the math will simply be done and expressed correctly for the player. It's just trying to get them to understand this diminishing return mathematics correctly when pondering whether to add more Withdrawal value that will be interesting... maybe just a text note that comes up under the right condition (like on a promotion one is looking to select, but NOT on a promotion your unit already has...)
 
I just want to make sure I'm doing this right, is this code the right way to make withdrawal multiplicative?
PHP:
void CvUnit::changeExtraWithdrawal(int iChange)															
{
	//ls612: Withdrawal is now multiplicative, so there is dimishing returns
	m_iExtraWithdrawal += ((iChange * std::max(0,100 - m_iExtraWithdrawal)) / 100);
	FAssert(getExtraWithdrawal() >= 0);
}

No, this doesn't work. Consider a promotion that has 50% withdraw. Suppose a unit starts with none, then gets the promotion. The above logic is applied and it winds up with 50 (so far so good). Now suppose it loses the promotion, so the above gets called with -50 as the promotion is taken away.

-50 * std::max(0,100- 50)/100 = -25 so the value winds up as 25 instead of 0...

The way to do this (if you want it to behave multiplicatively and symmetrically so that addition and removal have cancelling effects) is with logs. You keep as the member variable the log of the total withdrawal and when asked to return the modifier you return the anti-log of the stored value. If you use base 10 logs each '1' you add multiplies the effect by 10, so (if you were to use base 10 logs) you'd add log(XML modifier/1000).

The slight issue it gives you is that it is impossible to represent 0, so this work best as a modifier applied to a base chance, but in this case the base chance used can just be 100% for (sum XML modifiers > 0) else 0 and you should get what you want.
 
No, this doesn't work. Consider a promotion that has 50% withdraw. Suppose a unit starts with none, then gets the promotion. The above logic is applied and it winds up with 50 (so far so good). Now suppose it loses the promotion, so the above gets called with -50 as the promotion is taken away.

-50 * std::max(0,100- 50)/100 = -25 so the value winds up as 25 instead of 0...

The way to do this (if you want it to behave multiplicatively and symmetrically so that addition and removal have cancelling effects) is with logs. You keep as the member variable the log of the total withdrawal and when asked to return the modifier you return the anti-log of the stored value. If you use base 10 logs each '1' you add multiplies the effect by 10, so (if you were to use base 10 logs) you'd add log(XML modifier/1000).

The slight issue it gives you is that it is impossible to represent 0, so this work best as a modifier applied to a base chance, but in this case the base chance used can just be 100% for (sum XML modifiers > 0) else 0 and you should get what you want.

Wouldn't that make it accelerate? That isn't what I'm trying to do here, I want it to be as you add more withdrawal it takes that percent of the difference between what you currently have and 100%, so unless a promotion gives 100% withdrawal you will asymptotically approach 100% as you get more and more promotions, sort of a diminishing returns effect.
 
Wouldn't that make it accelerate? That isn't what I'm trying to do here, I want it to be as you add more withdrawal it takes that percent of the difference between what you currently have and 100%, so unless a promotion gives 100% withdrawal you will asymptotically approach 100% as you get more and more promotions, sort of a diminishing returns effect.

Oh I see what you mean. None-the-less my point about your suggested calculation remains -adding then removing the same amount doesn't leave you back where you started.

You should probably do something like TB suggested and just let the stored value be limitless and transform it via a lookup table (or mathematical function if you can find a suitable one) to the actual effective withdrawal. The function/lookup table should introduce very little distortion for small numbers and progressively compress for larger ones such that it closes asymptotically on 100 as the underlying raw total approaches infinity.

For example:

100 - 100/(1 + modifier/50)

which never reaches 100, though I distorts low modifiers more than you'd want, so it's just an example rather the right answer really (which is why a hand-crafted lookup able with linear interpolation between the hand-crafted points might be best).
 
@Koshling: What would be the best way to represent 'a mathematical process that preserves the first 50%, then any value over that continue to divide by half per 50 cumulative. Thus 100 = 75, 150 = 87(.5), 200 = 93(.75), 250 = 96(.975), 300 = 98(.5375) etc...' in code?
 
@Koshling: What would be the best way to represent 'a mathematical process that preserves the first 50%, then any value over that continue to divide by half per 50 cumulative. Thus 100 = 75, 150 = 87(.5), 200 = 93(.75), 250 = 96(.975), 300 = 98(.5375) etc...' in code?

Agreed, this is what I'm trying to do more or less. The formula is piecewise, but the problem would be getting it to work nicely with various sources of withdrawal (and pursuit, which I hope you change to match the scheme we come up with).
 
sigh... did you read why pursuit shouldn't be changed? You're just hoping I'm going to convince myself that you're right without trying to persuade me in any way?

Since I've already explained this, and I haven't gotten any counterarguments from you I'm confused as to why you think I'd want Pursuit to play like this as well?

The whole concept is intended to demand that pursuit not be ignored as a line of defense by purposefully enabling 100%+ withdrawal chances. You haven't countered to that point, nor others that point at the math being weighted heavily towards the lesser developed pursuit value, so why would I want it to not work that way?

I'm not saying I'm 10000% against the idea just that I don't see why you'd want to cut out a strategic need that the system was very much intended to demand of the player to maintain a strong defense in the same way that taking bombarding units to break down city defenses is necessary to wage a successful attack on a city.

What do you mean by piecewise? Trying to identify all the ways values can be tallied into the withdrawalPossibility total and manipulating the WAY they add is terribly overcomplicating the whole picture if that's what you mean.

So an answer to the above, which I could work out over a day or two of focused thought on the subject, would certainly be the best way to implement. I just kinda figured Koshling's a better math head than me ;)

EDIT: Were you hoping to be able to use Pursuit in the main and have it work in in the way you're suggesting? That might explain to me why you have such a strong feeling on this issue... and we could try to figure out some kind of a compromise if necessary. We may want to not act on withdrawalPossibility but rather act only on the final withdrawal probability actually taking place during battle instead (and in the battle hover help popup).
 
Agreed, this is what I'm trying to do more or less. The formula is piecewise, but the problem would be getting it to work nicely with various sources of withdrawal (and pursuit, which I hope you change to match the scheme we come up with).

The sources are irrelevant. All sources make up the total (as now), which is no capped in any way. The total is then converted to an effective percentage when it needs to be retrieved for use (in get access method). You just use a lookup table to do the conversion and interpolate between points. So suppose the lookup table has these values:

0 -> 0
50 -> 50
75 -> 70
90 -> 85
100 -> 88
200 -> 95
1000 -> 99

To convert the current total to the effective percentage you figure out which two points in the table it's between, then interpolate between their mapped values. So suppose the total value (from all sources) is 150. That's in the interval between the 100 and 200 points in the table, and its half way between, so the result is half way between their looked-up values - i.e. -(88 + 95)/2 == 91.5
 
EDIT: Were you hoping to be able to use Pursuit in the main and have it work in in the way you're suggesting? That might explain to me why you have such a strong feeling on this issue... and we could try to figure out some kind of a compromise if necessary. We may want to not act on withdrawalPossibility but rather act only on the final withdrawal probability actually taking place during battle instead (and in the battle hover help popup).

I was hoping sort of like that. Essentially withdrawal would work how you envisioned above, and pursuit would work the same except it's numbers would be negative (and ofc the total can't go below 0).

So if you have a unit with 100 raw withdrawal being attacked by a unit with 50 raw pursuit the withdrawal would total to be positive 75% and the pursuit would total to be -50%, so the net would be a 25% chance of withdrawal.

If the raw withdrawal was 200 and the raw pursuit was 100, then the Withdrawal would be +93.75% and Pursuit would be -75%, so the net would be 18.75%. This would discourage people from trying to spam either one, as otherwise things could get out of hand real quick.

I'm sorry if I'm explaining this poorly, but if we keep it additive and have the scale of numbers you are suggesting Withdrawal and Pursuit will become the most important stats to the exclusion of anything else, which is really bad.
 
I don't believe it would become that important, not when other numbers are acting on similar lines. Particularly when a unit that withdraws usually does so just as its about to die and simply withdraws instead, a shattered wreck but alive. Vulnerable to counterattack if not protected. I've never valued withdrawal much in BtS for that reason. Usually better to gain outright strength to increase your chances of survival and triump while exiting the battle with higher hp remaining and a dead enemy rather than an alive one.

Honestly, even now a withdrawal unit that has over 100% chance to withdraw still seems like it must've wasted a LOT of potential STRENGTH on all that ability to make sure it can limp out of a fight at the last minute. Such a unit would not frighten me... Even with Defensive Withdrawal on, if I simply leave it no safe place to run (where it is not threatened) then it cannot flee when I attack it.

But that aside, I don't mind working the pursuit into your vision in the core BUT it should NOT work as you just stated because that math so heavily favors lesser developed units and REALLY makes mastering withdrawal OR pursuit on a unit pretty much worthless.

Instead, I would simply calculate the sum total withdrawal probability being checked IN combat. Currently the probability is withdrawal - pursuit, right? So we take THAT number and manipulate it according to the method Koshling just posted. That'll have to be done in the combat programming but you could make a function that calculates this and send the programming through that routine wherever necessary, which happens a few times in the combat processing, odds determining, and combat help popup. It's a pain to do it at this stage but its the only way to make the math fair.

Thus, you'd have 100 withdrawal - 50 pursuit = 50 overall chance of withdrawal and that would still equate to 50 overall chance of withdrawal. But if you had 150 withdrawal and 50 pursuit, you'd take the 100 and it would end up being a 75% overall chance of withdrawal.

In otherwords, process only the final total, not withdraw and pursuit independently because then they don't fairly compare if you do.
 
I don't believe it would become that important, not when other numbers are acting on similar lines. Particularly when a unit that withdraws usually does so just as its about to die and simply withdraws instead, a shattered wreck but alive. Vulnerable to counterattack if not protected. I've never valued withdrawal much in BtS for that reason. Usually better to gain outright strength to increase your chances of survival and triump while exiting the battle with higher hp remaining and a dead enemy rather than an alive one.

Honestly, even now a withdrawal unit that has over 100% chance to withdraw still seems like it must've wasted a LOT of potential STRENGTH on all that ability to make sure it can limp out of a fight at the last minute. Such a unit would not frighten me... Even with Defensive Withdrawal on, if I simply leave it no safe place to run (where it is not threatened) then it cannot flee when I attack it.

But that aside, I don't mind working the pursuit into your vision in the core BUT it should NOT work as you just stated because that math so heavily favors lesser developed units and REALLY makes mastering withdrawal OR pursuit on a unit pretty much worthless.

Instead, I would simply calculate the sum total withdrawal probability being checked IN combat. Currently the probability is withdrawal - pursuit, right? So we take THAT number and manipulate it according to the method Koshling just posted. That'll have to be done in the combat programming but you could make a function that calculates this and send the programming through that routine wherever necessary, which happens a few times in the combat processing, odds determining, and combat help popup. It's a pain to do it at this stage but its the only way to make the math fair.

Thus, you'd have 100 withdrawal - 50 pursuit = 50 overall chance of withdrawal and that would still equate to 50 overall chance of withdrawal. But if you had 150 withdrawal and 50 pursuit, you'd take the 100 and it would end up being a 75% overall chance of withdrawal.

In otherwords, process only the final total, not withdraw and pursuit independently because then they don't fairly compare if you do.

It doesn't matter if it is almost dead if you have your SoD right there. Making withdrawal happen more is not somethign I'd particularily like to see, with the sheer number of units we have now it already takes forever to do anything militarily. Little things like this make me less than excited for the combat mod to be coming.
 
Really? But withdrawal is such a useless waste of ability development as it is now! In just about every case where you can successfully withdraw, you COULD have defeated the unit instead if you'd focused on combat modifiers! But it could be pretty cool if you could actually have withdrawal be an effective strategy. For example, going in and poisoning your opponent before withdrawing...

And then, with your opponent being able to counter it with pursuit units makes it one of the many ways you can strategically define your attack methods.

The whole point of the combat mod is to make no one strategy always a good one but to ask us to find the cracks in our opponent's armor, to attack in the way they are least prepared for. This makes it far more like actual combat - strike where your opponent is weak but if you over-rely on any given strategy, it will be you who is the one who may be savagely struck where you were not prepared for that kind of attack.

If you want battle to be a simple armwrestle affair of strength vs strength then the mod is not what you're looking to play, sure. But that's why it'll all be optional ;)

And to be honest, the only part of the game I'm really enjoying is the battle... the rest of it is all in preparation for that.
 
Code:
	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		if (GET_PLAYER((PlayerTypes)iI).getTeam() == getID() && GET_PLAYER((PlayerTypes)iI).isAlive())
		{
			for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
			{
				GET_PLAYER((PlayerTypes)iI).[COLOR="Red"]changeCommerceRateModifier[/COLOR](((CommerceTypes)iJ), GC.getTechInfo(eTech).[COLOR="Red"]getCommerceModifier[/COLOR](iJ) * iChange);
			}
		}
	}
	Note that the first 2 lines there are already set up in CvTeam so its only the rest of it that should go within the bracket after:
	if (GET_PLAYER((PlayerTypes)iI).getTeam() == getID() && GET_PLAYER((PlayerTypes)iI).isAlive())
Note the red is all that's different from the previous example I gave, in this case for the global % modifier. When I say Global in this case, I mean for the whole nation, not for all civs.

And as for processing? Done and done. This leaves just the text and ai remaining. I can help with the text but as I said, tech ai is something I haven't looked into much. I could sort that out too though with enough time and if you leave it for now, either Koshling will come around and instruct you there or I will figure it out (which I will sooner or later) and let you know (or you may have been able to sort it out yourself by then.)

<snip>

So, in yesterday's commit I implemented these new tags on two techs, Feudalism and education. Each got -3% :gold:, but when I recalculated modifiers there was closer to -50% :gold: from my income! I think that this is broken somehow, but my question is where?

Edit: I think I may have found the problem. The change is actually processed in this block of code

Code:
for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
			{
				GET_PLAYER((PlayerTypes)iI).changeCommerceRateModifier(((CommerceTypes)iJ), GC.getTechInfo(eTech).getCommerceModifier(iJ) * iChange);
			}

Why is the getCommerceModifier(iJ) value being multiplied by the iChange param in the processTech function? Isn't that value the iChange param for the changeCommerceRateModifier function?
 
So, in yesterday's commit I implemented these new tags on two techs, Feudalism and education. Each got -3% :gold:, but when I recalculated modifiers there was closer to -50% :gold: from my income! I think that this is broken somehow, but my question is where?

Edit: I think I may have found the problem. The change is actually processed in this block of code

Code:
for (int iJ = 0; iJ < NUM_COMMERCE_TYPES; iJ++)
			{
				GET_PLAYER((PlayerTypes)iI).changeCommerceRateModifier(((CommerceTypes)iJ), GC.getTechInfo(eTech).getCommerceModifier(iJ) * iChange);
			}

Why is the getCommerceModifier(iJ) value being multiplied by the iChange param in the processTech function? Isn't that value the iChange param for the changeCommerceRateModifier function?

No. iChange in the tech processing is always +1 or -1 (for getting the tech or losing it, though the latter never happens in practice I don't think), so in a recalc it will always be +1 as the techs are replayed during the recalc
 
Yep. iChange is used as a processing in/out standard method on just about all game effects from traits to promotions. We may not currently have any way to lose a tech but if we ever did, it'd be nice that tech tags followed the same template model. iChange is basically saying it's either positive or negative. Nothing more.
 
No. iChange in the tech processing is always +1 or -1 (for getting the tech or losing it, though the latter never happens in practice I don't think), so in a recalc it will always be +1 as the techs are replayed during the recalc

OK. I am still trying to figure out how this could be off by so much. Could it somehow be double-counting the modifiers from everyone on a team? Because that code looks fine to me (excepting that there should probably be a check to make sure that the commerce modifier isn't 0, but that wouldn't cause this problem).
 
Back
Top Bottom