PieceOfMind's Advanced Combat Odds

I think you're probably right on the unit selected. Do you think that means you'd need to trace this back to SelectionGroup.cpp? It's possible, but all the header stuff should be imported from that anyway if it's used in CvUnit. One thing I'm curious about to, if you think this would track down to the Selection Group file, what variable or function name would it be refrencing?
 
The function uses the selection list to query for the best attacker for the passed-in plot. It then asks the plot for the best defender given the attacker. I think you need to inject the switcharoo code here.

You need to decide how to pick the attacker on the target plot. I don't know if you can create a selection group out of units without causing them to be removed from their actual selection groups, so the first solution is to pick the first combat unit of a player at war with the human. You can then use CvPlot::getBestDefender() to pick the human's defender. Finally you can use CvUnit::AI_attackOdds() to calculate the odds.

If you verify that this is what you want or specify how it should behave differently, I'll see if I can write the code to do it. It doesn't seem too difficult as I've described it above.
 
if (iView & GC.getDefineINT("ACO_Option_ShowUnroundedXP"))//everything detail
{


szString.append(gDLL->getText("TXT_ACO_UnroundedXP"));
szString.append(gDLL->getText("TXT_ACO_Unharmed")); // del it
szString.append(gDLL->getText("TXT_KEY_COLOR_POSITIVE"));
szTempBuffer.Format(L"%.2f%",AttXP); // %.2f%%
szString.append(szTempBuffer.GetCString());
szString.append(gDLL->getText("TXT_KEY_COLOR_REVERT"));
szString.append(gDLL->getText("TXT_ACO_VS"));
szString.append(gDLL->getText("TXT_KEY_COLOR_NEGATIVE"));
szTempBuffer.Format(L"%.2f%",DefXP); // %.2f%%
szString.append(szTempBuffer.GetCString());
szString.append(gDLL->getText("TXT_KEY_COLOR_REVERT"));


}
 
@ztjal

Whenever you post code it helps to encase them in code tags: [CODE]Code Fu[/CODE]

It makes it far more readable, plus if your code is good to go, you can just cut and paste it that way :)
 
if (iView & GC.getDefineINT("ACO_Option_ShowUnroundedXP"))//everything detail
{


szString.append(gDLL->getText("TXT_ACO_UnroundedXP"));
szString.append(gDLL->getText("TXT_ACO_Unharmed")); // del it
szString.append(gDLL->getText("TXT_KEY_COLOR_POSITIVE"));
szTempBuffer.Format(L"%.2f%",AttXP); // %.2f%%
szString.append(szTempBuffer.GetCString());
szString.append(gDLL->getText("TXT_KEY_COLOR_REVERT"));
szString.append(gDLL->getText("TXT_ACO_VS"));
szString.append(gDLL->getText("TXT_KEY_COLOR_NEGATIVE"));
szTempBuffer.Format(L"%.2f%",DefXP); // %.2f%%
szString.append(szTempBuffer.GetCString());
szString.append(gDLL->getText("TXT_KEY_COLOR_REVERT"));


}

Thanks.

Now fixed. By the way, from the comments you put on the two formatting lines, it looks like you misunderstood the point of that bit of info. The unrounded xp is not meant to have "%" signs. It is the XP you would get if there wasn't rounding. It's not very useful at the best of times (which is why I've now left it disabled as default, and why I didn't spot this bug already), but in the past I've sometimes wanted to know when I was really close to crossing an XP threshold so would hold off on a certain promotion. e.g. if I have 8XP and could go into battle at 98% odds for 2xp, I might delay promoting the unit if the unrounded xp is 2.05 or something like that.
 
Here is the the mod with the bug fixed including the fixed source file (and no other noteworthy changes).

Advanced Combat Odds v1.31
 

Attachments

Looking at that code snippet, I'm guessing that there are a few places where you use this text pattern:

<color positive>text</color> vs. <color negative>text</color>​

You could create a single VS string in XML and plug in the two [text] strings. Also, you can change colors in C++ pretty easily as well using SETCOLR or something similar; I can look it up if you're interested, but the missing O is intended. It's not a big deal, and looking up several text strings for a hover will not be a performance issue, but it makes the code a little cleaner I think IMHO.
 
EF, I moved "vs." to the XML because of its alternate translation in other languages.

i couldn't figure out a way to use SETCOLR and ENDCOLR in a szTempBuffer.Format() expression coupled with a text entry from XML. Could you post an example of what you mean?
 
Here's a modified random example I pulled from CvGameTextMgr.cpp:

Code:
CvWString szTempBuffer;

...

szTempBuffer.Format(L"%.2f", fValue);
szString.append(NEWLINE);
szString.append(gDLL->getText("TXT_KEY_MISC_CHANCE_OF_REVOLT", szTempBuffer.GetCString()));

So I would rewrite the code above as

Code:
CvWString szTempBuffer1;
CvWString szTempBuffer2;

szTempBuffer1.Format(L"%.2f", AttXP);
szTempBuffer2.Format(L"%.2f", DefXP);
szString.append(gDLL->getText("TXT_ACO_UnroundedXP"));
szString.append(gDLL->getText("TXT_ACO_VS", szTempBuffer1.GetCString(), szTempBuffer2.GetCString()));

and change TXT_ACO_VS to be

Code:
[TEXT_COLOR_POSITIVE]%s1[COLOR_REVERT] vs. [TEXT_COLOR_NEGATIVE]%s2[COLOR_REVERT]
 
Here's a modified random example I pulled from CvGameTextMgr.cpp:

Code:
CvWString szTempBuffer;

...

szTempBuffer.Format(L"%.2f", fValue);
szString.append(NEWLINE);
szString.append(gDLL->getText("TXT_KEY_MISC_CHANCE_OF_REVOLT", szTempBuffer.GetCString()));

So I would rewrite the code above as

Code:
CvWString szTempBuffer1;
CvWString szTempBuffer2;

szTempBuffer1.Format(L"%.2f", AttXP);
szTempBuffer2.Format(L"%.2f", DefXP);
szString.append(gDLL->getText("TXT_ACO_UnroundedXP"));
szString.append(gDLL->getText("TXT_ACO_VS", szTempBuffer1.GetCString(), szTempBuffer2.GetCString()));

and change TXT_ACO_VS to be

Code:
[TEXT_COLOR_POSITIVE]%s1[COLOR_REVERT] vs. [TEXT_COLOR_NEGATIVE]%s2[COLOR_REVERT]

Done.

I understand how gDLL->getText() works a bit better now. Thanks.

v1.32 attached.
 

Attachments

Just a heads up. There is a bug in v1.32, caused by part of the changes I made:

Something is going wrong with the following code when the attacker and/or defender is hurt.

Code:
                if (pAttacker->isHurt())
                {

                    szTempBuffer.Format(L"%.2f (%d/%d%s)",
                                        ((pAttacker->getDomainType() == DOMAIN_AIR) ? pAttacker->airCurrCombatStrFloat(pDefender) : pAttacker->currCombatStrFloat(NULL, NULL)),
                                        pAttacker->currHitPoints(),pAttacker->maxHitPoints(),
                                        gDLL->getText("TXT_ACO_HP"));
                }
                else
                {
                    szTempBuffer.Format(L"%.2f",
                                        ((pAttacker->getDomainType() == DOMAIN_AIR) ? pAttacker->airCurrCombatStrFloat(pDefender) : pAttacker->currCombatStrFloat(NULL, NULL)));
                }


                if (pDefender->isHurt())
                {
                    szTempBuffer2.Format(L"%.2f (%d/%d%s)",
                                        pDefender->currCombatStrFloat(pPlot, pAttacker),
                                        pDefender->currHitPoints(),pDefender->maxHitPoints(),
                                        gDLL->getText("TXT_ACO_HP"));
                }
                else
                {
                    szTempBuffer2.Format(L"%.2f",
                                        pDefender->currCombatStrFloat(pPlot, pAttacker));
                }

                szString.append(gDLL->getText("TXT_ACO_VS", szTempBuffer.GetCString(), szTempBuffer2.GetCString()));
I must have done something illegal, but I'm not sure what.


This is the XML entry for TXT_ACO_VS
Code:
<English>[COLOR_POSITIVE_TEXT]%s1[COLOR_REVERT] vs. [COLOR_NEGATIVE_TEXT]%s2[COLOR_REVERT]</English>
 
What is the problem?

  • Doesn't compile?
  • Crash?
  • Wrong output? What is it?

Run-time. Looks almost like an infinite loop or something. Game doesn't crash but it's spitting out many lines of rubbish.
Text flashes in the hover box on and off like how the OOS errors do. It only seems to happen when one or both are injured and in particular the "HP" part looks like it's causing the problem. Can I not put a gDLL-gettext() as an argument in a TempBuffer.Format()?

EDIT
See attachment for a pic of what is sometimes happening.
 

Attachments

  • Civ4ScreenShot0731.JPG
    Civ4ScreenShot0731.JPG
    291.8 KB · Views: 94
That looks like it should work. You could try adding .GetCString() after the getText() call. Another way to rewrite it would be this:

Code:
szTempBuffer.Format(L"%.2f",
        ((pAttacker->getDomainType() == DOMAIN_AIR) ? pAttacker->airCurrCombatStrFloat(pDefender) : pAttacker->currCombatStrFloat(NULL, NULL)));
if (pAttacker->isHurt())
{
    szTempBuffer.append(L" ");
    szTempBuffer.append(gDLL->getText("TXT_ACO_INJURED_HP", 
            pAttacker->currHitPoints(), pAttacker->maxHitPoints()));
}

And create TXT_ACO_INJURED_HP as

Code:
%d1/%d2HP

I seem to recall having issues with injecting the text from getText() into a Format() call. This avoids that altogether and is slightly cleaner in that the strength part is done once whether or not the unit is injured (avoids code duplication.
 
Thanks EF, that worked.

v1.33 attached to this post.

Again, nothing new except the bugfix for the bug from v1.32
 

Attachments

Code:
				szTempBuffer.Format(L"%.2f",
									((pAttacker->getDomainType() == DOMAIN_AIR) ? pAttacker->airCurrCombatStrFloat(pDefender) : pAttacker->currCombatStrFloat(NULL, NULL)));

				if (pAttacker->isHurt())
				{
					szTempBuffer.append(L" (");
					szTempBuffer.append(gDLL->getText("TXT_ACO_INJURED_HP",
													pAttacker->currHitPoints(),
													pAttacker->maxHitPoints()));
					szTempBuffer.append(L")");
				}


				//szTempBuffer2.Format(L"%.2f",
				//					((pAttacker->getDomainType() == DOMAIN_AIR) ? pAttacker->airCurrCombatStrFloat(pDefender) : pAttacker->currCombatStrFloat(NULL, NULL))
				//					);

				szTempBuffer2.Format(L"%.2f",
									pDefender->currCombatStrFloat(pPlot, pAttacker)
									);

				if (pDefender->isHurt())
				{
					szTempBuffer2.append(L" (");
					szTempBuffer2.append(gDLL->getText("TXT_ACO_INJURED_HP",
													pDefender->currHitPoints(),
													pDefender->maxHitPoints()));
					szTempBuffer2.append(L")");
				}

				szString.append(gDLL->getText("TXT_ACO_VS", szTempBuffer.GetCString(), szTempBuffer2.GetCString()));
 
If you're saying to replace the commented out lines with the lines below it, it would be clearer to use [s]strikeout[/s] on the removed lines and [b]bold[/b] and a different color on the added lines.
 
:facepalm: argh I've been too rushed of late. Again I'm surprised I didn't pick up a stupid error.

Thanks again ztjal, but I agree with EF that you could really make your code suggestions a bit clearer. It took me a minute to work out what you were saying.

Simply saying "For defender strength you've copy pasted the attacker strength by mistake" might have been easier.

v1.34 attached with this fixed.

I accidentally left ACO_SwapViews enabled in this zip and possibly a couple of the previous ones. Just change it back to 0.
 

Attachments

v1.4 has been posted.

Nothing different since v1.34. Just changing the main download for the bug-less (hopefully) version.
 
Back
Top Bottom