PieceOfMind's Advanced Combat Odds

It wol't let you manage attachments from editing

You need to click "Go Advanced" to get to the attachments I think.

Here's a new random suggestion: show the details for the unit that will defend on the first line. I may add this as a separate feature to BULL since it's not related to the odds necessarily. It would be easy because it can just call out to the function that does this for the plot hover (I hope).
 
I'm trying to now add the double XP calculation for the leadership promotions, but can't figure it out. Everything I try failes to compile: Basically I've been looking through the code and finding instances where a promotion is called for, then trying to use that code to find if the unit has the leadership promotion. It keeps failing to compile, undlecared identifiers and what not (Thought I had it with this ePromotion call, but it said undeclared identifier ePromotion when compiling).

Any ideas?

Here is where the XP is calculated in the code in this modcomp, if it helps:
Minimum XP
Code:
                int iExperience;
                if (pAttacker->combatLimit() < 100)
                {
						iExperience        = GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL")			
                }
                else
                {
                    iExperience        = (pDefender->attackXPValue() * iDefenderStrength) / iAttackerStrength;
                    iExperience        = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
                }

                int iDefExperienceKill;
                    iDefExperienceKill = (pAttacker->defenseXPValue() * iAttackerStrength) / iDefenderStrength;
                    iDefExperienceKill = range(iDefExperienceKill, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
XP that needs calculation
Code:
                float AttXP = 4.0f/CombatRatio;
                float DefXP = 2.0f*CombatRatio;
 
Code:
               if (pAttacker->combatLimit() < 100)
				{
					for (int iPromotionIndex = 0; iPromotionIndex < numPromotionInfos; iPromotionIndex++)
							{
								PromotionTypes ePromotion = (PromotionTypes)iPromotionIndex;
								if (pUnit->isHasPromotion(ePromotion))
							}
									if (GC.getPromotionInfo(ePromotion).getExperiencePercent() != 0) {
								{
									iExperience        = ( ( GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL") )*2		
								}	
								} eles {
									iExperience        = GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL")			
								}
I tried a bunch of things, but this was the last one I tried.
1>CvGameTextMgr.cpp(1796) : error C2065: 'numPromotionInfos' : undeclared identifier
 
Try this:

Code:
		int iExperienceModifier = 0;
		for (int ePromotion; ePromotion < GC.getNumPromotionInfos(); ++ePromotion)
		{
			if (pUnit->isHasPromotion((PromotionTypes)ePromotion) && GC.getPromotionInfo((PromotionTypes)ePromotion).getExperiencePercent() != 0)
			{
				iExperienceModifier += GC.getPromotionInfo((PromotionTypes)ePromotion).getExperiencePercent();
			}
		}
		int iExperience;
		if (pAttacker->combatLimit() < 100)
		{
			iExperience        = GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL")			
		}
		else
		{
			iExperience        = (pDefender->attackXPValue() * iDefenderStrength) / iAttackerStrength;
			iExperience        = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
		}
		if (iExperienceModifier != 0)
		{
			iExperience = iExperience * (100 + iExperienceModifier) / 100;
			// double-check that the experience is again limited or if it can be > max with leadership
			iExperience = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
		}
 
I was worried about this:

1>CvGameTextMgr.cpp(1796) : error C2065: 'pUnit' : undeclared identifier
I don't see in the code where it is declaring which unit is which, so I don't think a valid pUnit exists. Is this something that needs to be done in python?

edit: I just tried using pAttacker and got the warning: : warning C4700: local variable 'ePromotion' used without having been initialized. I'll see what I can do with that, I'll try doubling it up and adding in pDeffender and see if that works.
It did compile though :)
Nope no dice, that warning about ePromotion not being initialized must mean it never looked for the promotion.
 
Oops, I just copied your code and modified it. ePromotion needs to be initialized with 0:

Code:
for (int ePromotion [B][COLOR="Blue"]= 0[/COLOR][/B]; . . .
 
Well it's half working. It's not applying the double XP to withdrawls, and it also seems to cap at 10XP. I'll mess around with this and see if I can figure anything out. If any thoughts come to your mind, please share them, I always need the help.
 
It's not applying the double XP to withdrawls.

Make sure that it is adding iExperience in this case and not calling GC.getDefineINT("EXPERIENCE_FROM_WITHDRAWL") again.

It also seems to cap at 10XP.

That's because MAX_EXPERIENCE_PER_COMBAT is 10, and the line with the range(...) call is limiting the XP to be in [min, max]--in this case [1, 10]. Should it allow it to go to 20 with the modifier? If so, remove the second range() line and note the comment I put above it just for you.
 
That's because MAX_EXPERIENCE_PER_COMBAT is 10, and the line with the range(...) call is limiting the XP to be in [min, max]--in this case [1, 10]. Should it allow it to go to 20 with the modifier? If so, remove the second range() line and note the comment I put above it just for you.
I actually figured that out on my own :p, and was about to change it, when I double checked in here:
Should it allow it to go to 20 with the modifier?
That's a good question, I don't know if the 10XP cap applies to leadership. Anyone know the answer to that?

Well since that's done (just need to plunk in the same code for the defender now). It's time for the next project, and this one, I have no idea where even to start.

How does one combine the HP display bars, in the expected outcome HP display? This needs to be done so that the top of the pane doesn't get lopped off when there are many HP outcomes, basically a function needs to be added where the % chance of the HP values under 0.01% are added, and then the HP is listed as a range.

Here is the code for that:
Code:
                    //START DEFENDER DETAIL HP HERE
                    if (tmpDetail > 2)//everything detail
                    {
                        for (int n_D = iNeededRoundsAttacker-1; n_D >= 0; n_D--)
                        {

                            float prob = 100.0f*(getCombatOddsSpecific(pAttacker,pDefender,iNeededRoundsDefender,n_D)+(getCombatOddsSpecific(pAttacker,pDefender,iNeededRoundsDefender-1,n_D)));
                            szTempBuffer.Format(SETCOLR L"%dHP" ENDCOLR L" %.2f%%",
                                                TEXT_COLOR("COLOR_NEGATIVE_TEXT"),((pDefender->currHitPoints()) - n_D*iDamageToDefender),prob);
                            szString.append(NEWLINE);
                            int pixels = (int)(Scaling_Factor*prob + 0.5)+2;  // 1% per pixel
                            int fullBlocks = (pixels-2) / 10;
                            int lastBlock = (pixels-2) % 10;
                                szString.append(L"<img=Art/ACO/red_bar_left_end.dds>");
                                for (int iI = 0; iI < fullBlocks; ++iI)
                                {
                                    szString.append(L"<img=Art/ACO/red_bar_10.dds>");
                                }
                                if (lastBlock > 0)
                                {
                                    szTempBuffer2.Format(L"<img=Art/ACO/red_bar_%d.dds>", lastBlock);
                                    szString.append(szTempBuffer2);
                                }
                                szString.append(L"<img=Art/ACO/red_bar_right_end.dds>");
                            szString.append(L" ");
                            szString.append(szTempBuffer.GetCString());

                        }
                    }
                    //END DEFENDER DETAIL HP HERE
I'll go and iron out the XP for leadership code, and hopefully someone will have an idea of where to start on this one.
 
Done with promotion modifying XP (for the leadership promotion, but it'll take into account new promos from mods or whatever that modify XP earning). Learned alot of C++ this go around, thanks for the help EmperorFool. Took me a few hours to finish it, had to create a new thing you need to define and give a value (what's that called) iWithdrawXP to get it to work. Figuring out how to do that was interesting. I supposed I could try looking this stuff up, but bumbling along and learning through trial and error is just alot more fun.

Anyway, this attachment has the shift click thing (hold down shift and the pane changes to Everything! level), and the XP is adjusted for promotions. One thing though, as above I don't know if XP modifying promotions effect the Max XP earnable (10XP max in default civ), so I've left the max cap in as is. The only Source Code that's changed from the original modcomp is CvGameTextMgr.

If anyone wants to give me direction on how to tackle merging those HP display bars, I'd be happy to work on it. Unfortunetly I don't even know how to begin doing that. Though I think I'll just start tinkering with that portion of the code anyway for the next couple hours and see what happens.
 
I can tell you that it is possible for units to get 20XP from combat. Try attacking a 15HP modern armor with a Drill IV/Combat II/Leadership warrior lol. (63% odds). That unit gains 20XP when he wins.

So as a guess, I'd say XP modifiers happen after the range restriction in 1 to 10. This surprised me as I originally would have guessed the opposite.

About merging the display bars, if you don't mind phungus, I'd be happy to do that. I've got one or two things to tidy up with the bars anyway. Just make sure you are keeping track of the changes you are making so it'll be easy enough to merge them when the time comes.

I'm grateful you have sorted out the shift key and XP issues. I'm wondering how the info for doubling of XP should be presented, as I think just doubling the number displayed may not always make me twig the XP is being doubled. Perhaps it will be worth writing something like:

Attack: 57% (2x2XP) (53.0HP)

or whatever modifier 2, 3 (maybe even 4? eg. leaderhip, great wall, IMP trait) is appropriate
 
Careful! The Leadership promotion gives x2 XP, but the Great Wall and Imperialist trait do not affect the XP earned--they only affect the XP-to-GGP conversion. That's why I recommended above to leave those things off or perhaps show them as a line like

* +100% Great General Points​

somewhere in the text.

As for the Leadership promotion, keep in mind that it is a percentage and could easily be set to 50%. Would you then show it as "1.5x2XP"? I would just multiply it out and show the final XP earned. The fact that the promotion is taken into consideration is a matter for the readme IMHO.
 
Ah you're right EF. I'm not thinking very clearly at the moment. All I know is that the actual applying of XP is done in CvUnit::resolveCombat().

Anything further than this code and I'm only making guesses.

Code:
if (isDead() || pDefender->isDead())
		{
			if (isDead())
			{
				int iExperience = defenseXPValue();
				iExperience = ((iExperience * iAttackerStrength) / iDefenderStrength);
				iExperience = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
				pDefender->changeExperience(iExperience, maxXPValue(), true, pPlot->getOwnerINLINE() == pDefender->getOwnerINLINE(), !isBarbarian());
			}
			else
			{
				flankingStrikeCombat(pPlot, iAttackerStrength, iAttackerFirepower, iAttackerKillOdds, iDefenderDamage, pDefender);

				int iExperience = pDefender->attackXPValue();
				iExperience = ((iExperience * iDefenderStrength) / iAttackerStrength);
				iExperience = range(iExperience, GC.getDefineINT("MIN_EXPERIENCE_PER_COMBAT"), GC.getDefineINT("MAX_EXPERIENCE_PER_COMBAT"));
				changeExperience(iExperience, pDefender->maxXPValue(), true, pPlot->getOwnerINLINE() == getOwnerINLINE(), !pDefender->isBarbarian());
			}

			break;
		}

EF,
How soon are you intending to have this BUG DLL done? I've a few things I'd like to tidy up before it goes in BUG.

Also, have we stopped for a moment to consider whether everyone will welcome this feature? I know there is a lot of room for debate when it comes to what does/doesn't get included in BUG, and although this information can be calculated in parallel to the game (heck, I have the java program that can run in the background doing the same thing as the ACO, and which I had been using before I made this), some people might consider it going too far beyond what was considered information the user was meant to know.

I wonder only because the calculations involved are, I'd imagine, beyond what many players can handle if they were asked to. I wouldn't call it a book keeping reduction if you know what I mean.

I'm all in favour of it, obviously because I started the mod, but I am wondering how well it will be received.
 
Well, I make everything I add to BUG optional, so players will be free to disable it if they wish. Perhaps we could make that easier by adding a "None" level of detail which shows the original information? It's pointless for the standalone version of your mod, or else why add it in, but it would make including it into BUG a breeze. :)
 
I can tell you that it is possible for units to get 20XP from combat. Try attacking a 15HP modern armor with a Drill IV/Combat II/Leadership warrior lol. (63% odds). That unit gains 20XP when he wins.

So as a guess, I'd say XP modifiers happen after the range restriction in 1 to 10. This surprised me as I originally would have guessed the opposite.
OK, Updated. This was much harder to code then I originally thought, but it is now finally working.
About merging the display bars, if you don't mind phungus, I'd be happy to do that. I've got one or two things to tidy up with the bars anyway. Just make sure you are keeping track of the changes you are making so it'll be easy enough to merge them when the time comes.
OK, I don't want to step on your toes. Mainly your modcomp was so cool, it got me motivated to messing with the SDK. Been avoiding it for the past two years, but this one, I had to add in the Shift function, and had to learn, once I started I was kind of stoked about coding in C++, and wanted to continue working on things. But it's your baby, and I think I've added in what I wanted to anyway.

I'm grateful you have sorted out the shift key and XP issues. I'm wondering how the info for doubling of XP should be presented, as I think just doubling the number displayed may not always make me twig the XP is being doubled. Perhaps it will be worth writing something like:

Attack: 57% (2x2XP) (53.0HP)
That's a good point, I decided a 2x2 display wasn't the best though. I've made it so the bonus XP awarded is now color coded Cyan, and shows up in the Unrounded XP line. Since the Everything! display is accessible by simply pressing shift I think this works well. One thing to note though is that if the XP modifier is negative (someone mods a -%XP promo), the line will be displayed as + -X.xx, I could have written a few more else, ifs to take that into account, but didn't really think it was worth it. The code should be pretty self explanitory though if you want to add that in.


As far as merging goes. Sorry, I haven't really commented anything, I'm done though, wol't be adding anything else if you want to work from this last attachment.

Here's what it looks like:
 
Lol, noticed from the pic one more thing I wanted to change. The XP for withdraw was still displayed as yellow in the low detail. Wanted it green, since it's not shared. In the Medium and High settings, HP shows up yellow for retreats, but changes to the split green and red at Everything. The other notworthy change from the default is that the HP statistical distribution bars follow a typical bell curve, and don't invert in the Deffender HP list.
 
Do you handle the case where the defender has the Leadership promotion? ;)

Download it and see :lol:
(yes)
The code only applies XP modifiers from promotions. This is because only promotions modify XP in default CIV4, so if someone adds in some other XP modifier, they have to do SDK work anyway. I figure they'll need to take that into account for their mod if they add another modifier in.
 
phungus,
It seems the updated XP has not affected the XP thresholds in the XP range display. That's understandable because the way I coded that line was pretty hard to alter. But it looks a little bit off at the moment with 6XP at R=1.1 and lower values on both sides of it. I'm thinking the bonus XP you have in cyan should instead go directly beside the XP displayed in both the Victory and Retreat Odds.

eg.
Victory: 68.05% for 3+3XP

Bonus XP is never going to be non-integer amounts anyway.


EF,
I don't think there's much point making a None detail setting. Just have the option to completely pass the new code (I can do this easily). Then I can have a simple if statement at each of the points where the old code would normally be printed, where I commented it out.

Also, are you aware of the limitations of this code at the moment? A few of the bits of information that are given depend on the assumed values of Max XP being 10, min XP being 1 and AttackerXP value (or whatever it's called) being 4 and the defender one being 2.

I haven't tested the code in any other mods so I'm not 100% sure what other things could be affected. There are other problems with the mod like the fact it will not tell you how much XP you won't get when you are fighting barbs/animals near their XP caps.



I have some working code now that combines HP bars when they are less than 0.5% (this value can be adjusted). This has significantly reduced the bar spamming problem. Note however that I have always included the lowest attacker HP bar individually in case retreat odds are included.

 

Attachments

  • condensed example 2.JPG
    condensed example 2.JPG
    121 KB · Views: 206
Top Bottom