Caption Update Distance

A forum for reporting bugs NOT related to custom plugins.

Moderator: MacroQuest Developers

gnatch
orc pawn
orc pawn
Posts: 10
Joined: Thu May 13, 2004 2:52 am

Caption Update Distance

Post by gnatch » Wed Jan 24, 2007 5:03 am

So,
Whilst playing with MQ2 I noticed that the spawn captions were not always the mq captions (aka the one with con colors, LDR, etc...) but would change once brought within a certain range. After searching in vain for a simple fix i dove into the code. I found that the distance at which the captions update was hard coded at 80.0f... about half of the distance from when the captions fade in. So i decided to fix it :) At first I hacked the numbers and recompiled and tested settings but then i decided to make it better. In other words, allow the user to customize the distance at which it updates the MQCaptions.
So... Here's what i changed in my build:

I understand i include a larger section of code than i changed i just want to keep the chunks intact so there's no confusion as to what i changed.

<In MQ2Spawns.cpp>(@line 537)
Change:

Code: Select all

VOID UpdateSpawnCaptions()
{
//	DebugSpew("UpdateSpawnCaptions()");
	DWORD N;
	DWORD Count=0;
	for (N = 0 ; N < 120 ; N++)
	{
		if (PSPAWNINFO pSpawn=(PSPAWNINFO)EQP_DistArray[N].VarPtr.Ptr)
		if (pSpawn!=(PSPAWNINFO)pTarget)
		if (EQP_DistArray[N].Value.Float <=80.0f && gMQCaptions)
		{
			if (SetNameSpriteState(pSpawn,true))
			{
				SetNameSpriteTint(pSpawn);
				Count++;
				if (Count>=gMaxSpawnCaptions)
				{
					return;
				}
			}
		}
		else
		{
			return;
		}
	}
}
To:

Code: Select all

VOID UpdateSpawnCaptions()
{
//	DebugSpew("UpdateSpawnCaptions()");
	DWORD N;
	DWORD Count=0;
	for (N = 0 ; N < 120 ; N++)
	{
		if (PSPAWNINFO pSpawn=(PSPAWNINFO)EQP_DistArray[N].VarPtr.Ptr)
		if (pSpawn!=(PSPAWNINFO)pTarget)
		if (EQP_DistArray[N].Value.Float <=(float)gSpawnCaptionDistance && gMQCaptions)
		{
			if (SetNameSpriteState(pSpawn,true))
			{
				SetNameSpriteTint(pSpawn);
				Count++;
				if (Count>=gMaxSpawnCaptions)
				{
					return;
				}
			}
		}
		else
		{
			return;
		}
	}
}
<In MQ2Globals.h>(@line 55)

change:

Code: Select all

EQLIB_VAR BOOL gStringTableFixed;
EQLIB_VAR DWORD gMaxSpawnCaptions;
EQLIB_VAR BOOL gMQCaptions;
TO:

Code: Select all

EQLIB_VAR BOOL gStringTableFixed;
EQLIB_VAR DWORD gMaxSpawnCaptions;
EQLIB_VAR DWORD gSpawnCaptionDistance;
EQLIB_VAR BOOL gMQCaptions;
<In MQ2Globals.cpp>(@line 55)

Change:

Code: Select all

DWORD gGameState = 0;
DWORD gMaxSpawnCaptions=30;
BOOL gMQCaptions=TRUE;
DWORD ThreadID = 0;
BOOL g_Loaded = FALSE;
To:

Code: Select all

DWORD gGameState = 0;
DWORD gMaxSpawnCaptions=30;
DWORD gSpawnCaptionDistance=80;
BOOL gMQCaptions=TRUE;
DWORD ThreadID = 0;
BOOL g_Loaded = FALSE;
<In MQ2Main.cpp>(@line 146)

change:

Code: Select all

gMaxSpawnCaptions=GetPrivateProfileInt("Captions","Update",gMaxSpawnCaptions,Filename);
gMQCaptions = 1==GetPrivateProfileInt("Captions","MQCaptions",1,Filename); 
TO:

Code: Select all

gMaxSpawnCaptions=GetPrivateProfileInt("Captions","Update",gMaxSpawnCaptions,Filename);
gSpawnCaptionDistance=GetPrivateProfileInt("Captions","Distance",gSpawnCaptionDistance,Filename);
gMQCaptions = 1==GetPrivateProfileInt("Captions","MQCaptions",1,Filename); 
<In MQ2Commands.cpp>(@line 3005)

Change:

Code: Select all

VOID CaptionCmd(PSPAWNINFO pChar, PCHAR szLine)
{
	CHAR Arg1[MAX_STRING]={0};
	GetArg(Arg1,szLine,1);
	if (!Arg1[0])
	{
		SyntaxError("Usage: /caption <list|type <value>|update #|MQCaptions <on|off>>");
		return;
	}
	if (!stricmp(Arg1,"list"))
	{
		WriteChatf("\ayPlayer1\ax: \ag%s\ax",gszSpawnPlayerName[1]);
		WriteChatf("\ayPlayer2\ax: \ag%s\ax",gszSpawnPlayerName[2]);
		WriteChatf("\ayPlayer3\ax: \ag%s\ax",gszSpawnPlayerName[3]);
		WriteChatf("\ayPlayer4\ax: \ag%s\ax",gszSpawnPlayerName[4]);

		WriteChatf("\ayNPC\ax: \ag%s\ax",gszSpawnNPCName);
		WriteChatf("\ayPet\ax: \ag%s\ax",gszSpawnPetName);
		WriteChatf("\ayCorpse\ax: \ag%s\ax",gszSpawnCorpseName);
		return;
	}
	PCHAR pCaption=0;
	if (!stricmp(Arg1,"Player1"))
	{
		pCaption=gszSpawnPlayerName[1];
	} else if (!stricmp(Arg1,"Player2"))
	{
		pCaption=gszSpawnPlayerName[2];
	} else if (!stricmp(Arg1,"Player3"))
	{
		pCaption=gszSpawnPlayerName[3];
	} else if (!stricmp(Arg1,"Player4"))
	{
		pCaption=gszSpawnPlayerName[4];
	} else if (!stricmp(Arg1,"Pet"))
	{
		pCaption=gszSpawnPetName;
	} else if (!stricmp(Arg1,"NPC"))
	{
		pCaption=gszSpawnNPCName;
	} else if (!stricmp(Arg1,"Corpse"))
	{
		pCaption=gszSpawnCorpseName;
	} else if (!stricmp(Arg1,"Update"))
	{
		gMaxSpawnCaptions=atoi(GetNextArg(szLine));
		if (gMaxSpawnCaptions<8)
			gMaxSpawnCaptions=8;
		if (gMaxSpawnCaptions>70)
			gMaxSpawnCaptions=70;
		WritePrivateProfileString("Captions","Update",itoa(gMaxSpawnCaptions,Arg1,10),gszINIFilename);
		WriteChatf("\ay%d\ax nearest spawns will have their caption updated each pass.",gMaxSpawnCaptions);
		return;
	} else if (!stricmp(Arg1,"MQCaptions"))
	{
        gMQCaptions=(!stricmp(GetNextArg(szLine),"On"));
		WritePrivateProfileString("Captions","MQCaptions",(gMQCaptions?"1":"0"),gszINIFilename);
		WriteChatf("MQCaptions are now \ay%s\ax.",(gMQCaptions?"On":"Off"));
		return;
	}
	else
	{
		MacroError("Invalid caption type '%s'",Arg1);
		return;
	}
	strcpy(pCaption, GetNextArg(szLine));
	WritePrivateProfileString("Captions",Arg1,pCaption,gszINIFilename);
	ConvertCR(pCaption);
	WriteChatf("\ay%s\ax caption set.",Arg1);
}
To:

Code: Select all

VOID CaptionCmd(PSPAWNINFO pChar, PCHAR szLine)
{
	CHAR Arg1[MAX_STRING]={0};
	GetArg(Arg1,szLine,1);
	if (!Arg1[0])
	{
		SyntaxError("Usage: /caption <list|type <value>|update #(8-70)|distance #|MQCaptions <on|off>>");
		return;
	}
	if (!stricmp(Arg1,"list"))
	{
		WriteChatf("\ayPlayer1\ax: \ag%s\ax",gszSpawnPlayerName[1]);
		WriteChatf("\ayPlayer2\ax: \ag%s\ax",gszSpawnPlayerName[2]);
		WriteChatf("\ayPlayer3\ax: \ag%s\ax",gszSpawnPlayerName[3]);
		WriteChatf("\ayPlayer4\ax: \ag%s\ax",gszSpawnPlayerName[4]);

		WriteChatf("\ayNPC\ax: \ag%s\ax",gszSpawnNPCName);
		WriteChatf("\ayPet\ax: \ag%s\ax",gszSpawnPetName);
		WriteChatf("\ayCorpse\ax: \ag%s\ax",gszSpawnCorpseName);
		return;
	}
	PCHAR pCaption=0;
	if (!stricmp(Arg1,"Player1"))
	{
		pCaption=gszSpawnPlayerName[1];
	} else if (!stricmp(Arg1,"Player2"))
	{
		pCaption=gszSpawnPlayerName[2];
	} else if (!stricmp(Arg1,"Player3"))
	{
		pCaption=gszSpawnPlayerName[3];
	} else if (!stricmp(Arg1,"Player4"))
	{
		pCaption=gszSpawnPlayerName[4];
	} else if (!stricmp(Arg1,"Pet"))
	{
		pCaption=gszSpawnPetName;
	} else if (!stricmp(Arg1,"NPC"))
	{
		pCaption=gszSpawnNPCName;
	} else if (!stricmp(Arg1,"Corpse"))
	{
		pCaption=gszSpawnCorpseName;
	} else if (!stricmp(Arg1,"Update"))
	{
		gMaxSpawnCaptions=atoi(GetNextArg(szLine));
		if (gMaxSpawnCaptions<8)
			gMaxSpawnCaptions=8;
		if (gMaxSpawnCaptions>70)
			gMaxSpawnCaptions=70;
		WritePrivateProfileString("Captions","Update",itoa(gMaxSpawnCaptions,Arg1,10),gszINIFilename);
		WriteChatf("\ay%d\ax nearest spawns will have their caption updated each pass.",gMaxSpawnCaptions);
		return;
	} else if (!stricmp(Arg1,"Distance"))
	{
		gSpawnCaptionDistance=atoi(GetNextArg(szLine));
		WritePrivateProfileString("Captions","Distance",itoa(gSpawnCaptionDistance,Arg1,10),gszINIFilename);
		WriteChatf("Spawns as far away as \ay%d\ax will have their captions updated .",gSpawnCaptionDistance);
		return;
	} else if (!stricmp(Arg1,"MQCaptions"))
	{
        gMQCaptions=(!stricmp(GetNextArg(szLine),"On"));
		WritePrivateProfileString("Captions","MQCaptions",(gMQCaptions?"1":"0"),gszINIFilename);
		WriteChatf("MQCaptions are now \ay%s\ax.",(gMQCaptions?"On":"Off"));
		return;
	}
	else
	{
		MacroError("Invalid caption type '%s'",Arg1);
		return;
	}
	strcpy(pCaption, GetNextArg(szLine));
	WritePrivateProfileString("Captions",Arg1,pCaption,gszINIFilename);
	ConvertCR(pCaption);
	WriteChatf("\ay%s\ax caption set.",Arg1);
}
And lastly I added

Code: Select all

Distance=80
Into MacroQuest.ini under the [Captions] heading.

It seems to be working for me, if anyone is brave enough to try it on theirs let me know :)


-gnatch


<<Edit: was missing the V on the first VOID function :oops: >>
Last edited by gnatch on Wed Jan 24, 2007 6:49 pm, edited 2 times in total.

User avatar
fearless
Not a Psychic
Posts: 2684
Joined: Wed Mar 10, 2004 3:52 pm

Post by fearless » Wed Jan 24, 2007 10:23 am

windiff is your friend
Reading . . . it's not just for me.

[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
[quote="Ccomp5950"]Fearless showed me the light, you too shall learn.[/quote]

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Wed Jan 24, 2007 1:42 pm

The 80.0 was put in for performance reasons. It burns a lot of CPU and graphics horsepower to update all the captions in a zone even though they can't be seen...

User avatar
gimp
a grimling bloodguard
a grimling bloodguard
Posts: 584
Joined: Fri Oct 29, 2004 9:28 am
Location: internet

Post by gimp » Wed Jan 24, 2007 2:01 pm

Nice one! Will this make it into official MQ2 or shall i start patching my code?

User avatar
fearless
Not a Psychic
Posts: 2684
Joined: Wed Mar 10, 2004 3:52 pm

Post by fearless » Wed Jan 24, 2007 3:05 pm

gimp wrote:Nice one! Will this make it into official MQ2 or shall i start patching my code?
per dkaa's comment, I would think it is unlikely to make it into source . . .

Is there a prize for 2k posts?
Reading . . . it's not just for me.

[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
[quote="Ccomp5950"]Fearless showed me the light, you too shall learn.[/quote]

User avatar
gimp
a grimling bloodguard
a grimling bloodguard
Posts: 584
Joined: Fri Oct 29, 2004 9:28 am
Location: internet

Post by gimp » Wed Jan 24, 2007 3:13 pm

Well, judging from the posted code, and dkaa's comment i get the impression dkaa didnt check what the code changes. He argues why 80.0f is hard coded because of performance reasons, but the patch doesnt change that. It just makes it easily configurable from MacroQuest.ini, with the default set to 80.

I totally understand how wasteful it would be to caculate captions for all spawns in zone, but this isn't the case here.

Oh well, either if it never gets into official code or not, thanks gnatch for posting it.

User avatar
fearless
Not a Psychic
Posts: 2684
Joined: Wed Mar 10, 2004 3:52 pm

Post by fearless » Wed Jan 24, 2007 3:34 pm

gimp - I didn't read through the whole thing either, my bad.

That could be a good change.
Reading . . . it's not just for me.

[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
[quote="Ccomp5950"]Fearless showed me the light, you too shall learn.[/quote]

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Wed Jan 24, 2007 4:40 pm

I wasn't making any comment on the new code.

devNull
a ghoul
a ghoul
Posts: 121
Joined: Sat Mar 06, 2004 3:57 am

Post by devNull » Wed Jan 24, 2007 5:56 pm

dont_know_at_all wrote:The 80.0 was put in for performance reasons. It burns a lot of CPU and graphics horsepower to update all the captions in a zone even though they can't be seen...
From what I can tell, there are two checks to prevent going overboard on the number of captions updated:

Code: Select all

for (N = 0 ; N < 120 ; N++) 
and

Code: Select all

if (Count>=gMaxSpawnCaptions)
With that said, I had also previously changed the hardcoded 80.0f in my copy. Off the top of my head, I think I changed it to 140.0f or so which is where, in my case, I actually start to "see" the caption above things.

gnatch
orc pawn
orc pawn
Posts: 10
Joined: Thu May 13, 2004 2:52 am

gMaxSpawnCaptions

Post by gnatch » Wed Jan 24, 2007 6:46 pm

Another thing i noticed gMaxSpawnCaptions is capped at 70 if you set it over 70 in the ini it restricts it to 70...
In MQ2Commands.cpp

Code: Select all

      gMaxSpawnCaptions=atoi(GetNextArg(szLine)); 
      if (gMaxSpawnCaptions<8) 
         gMaxSpawnCaptions=8; 
      if (gMaxSpawnCaptions>70) 
         gMaxSpawnCaptions=70; 
sooooo setting the max distance higher doesn't change the fact that it won't update more than 70 /shrug
Additionally, by default Update=35 in the ini....

Personally, i set the distance to 200 to test it out and giants names would fade in before they would update to mqcaptions... so mine's set to 300 :D

-gnatch

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Re: Caption Update Distance

Post by Cr4zyb4rd » Sat Apr 12, 2014 11:24 am

yes ,gMaxSpawnCaptions is initialized to 30, set to 35 by MacroQuest_default.ini, and hard-limited to values 8-70 by the command to set it. The only time it's actually used is in a loop that's already limited to:
-a distance barely outside of melee range (the issue this post set out to address), a check made just before we check a solution-scoped global to determine if we should be executing this function at all
- to a maximum of 120 results with no regard to how much if any actual parsing/processing has been done. this seems somewhat arbitrary, but it's hard to tell when that 120 is the upper limit on an array of void pointers (sometimes.. it's a union) to void pointers. well not void pointers, PVOIDs. those are like void pointers in every way except we don't have to feel guilty if we don't put a "p" in front of their name. well wait no it's not a void pointer, it's an MQ2Internal::_MQ2VarPtr::Ptr.. which is a fancy way of saying PVOID.

At the very least this change should be merged, but IMO the distance check is of limited use in the first place. Its practical effect is having more information about some spawns on my screen available to me than others, and internals aside things like camera position and context dictate what's essential. The captions aren't something any bot or plugin will ever care about, and shouldn't be optimized as if they were.

Put another way, an evaluation is going to take time to do, but I can't see somebody bothering to write a complex caption with the intention that it only happens for things they're already standing nearly on top of. We've already taken away the String TLO and done other things to stop somebody from shooting themselves in the foot here.

Are the captions actually slowing anybody down in practice? They're easily disabled completely for anybody boxing, but it also would be fairly trivial to remove these limits and do something more adaptive.