Page 1 of 1

Team shirt colors

Posted: Wed Mar 14, 2012 4:10 pm
by Cobalt
I want to improve the stock ctfbot TeamGetShirt() routine so that it can use bitflags on a teamshirt float to check if a certain color is used.
The stock code is:

Code: Select all

float (float t, entity ent) TeamGetShirt =
{
	if ((t == TEAM_COLOR1))
	{
		team1shirt = (team1shirt + FLAG_CARRIED);
		if ((team1shirt == (TEAM_COLOR2 - FLAG_CARRIED)))
		{
			team1shirt = (team1shirt + FLAG_CARRIED);
		}
		if ((team1shirt == 2))
		{
			team1shirt = (team1shirt + FLAG_CARRIED);
		}
		if ((team1shirt > TEAM_COLOR2))
		{
			team1shirt = 0;
		}
		return (team1shirt);
	}
	else
	{
		team2shirt = (team2shirt + FLAG_CARRIED);
		if ((team2shirt == (TEAM_COLOR1 - FLAG_CARRIED)))
		{
			team2shirt = (team2shirt + FLAG_CARRIED);
		}
		if ((team2shirt == 6))
		{
			team2shirt = (team2shirt + FLAG_CARRIED);
		}
		if ((team2shirt > TEAM_COLOR2))
		{
			team2shirt = 0;
		}
		return (team2shirt);
	}
	return ((t - FLAG_CARRIED));

...which seems to increment the floats, however once a player or bot leaves, that color is now freed, but this system wont consider that color is now available. What I have in mind is to make the team2shirt and team1shirt use bitflags, and I think that we could just check if (team2shirt && BLUE1) , for example, tells us if that shirtcolor 0 is available or not. I would make shirtcolor 0 the first float, and so fourth so that BLUE16 is 32768. Same for the RED team set. I would probably use scratch1 and scratch2 to keep these values known from level to level. I had also thought of merely cycling through the player and bot entities using ' find ' to check if a color is used, but the bitflag idea sounds more effective. Comments or ideas anyone?

EDIT: Other thing I forgot to mention is will need to check if the shirt color is the opposing teams pant color and disallow it. Whats a good explanation of what .colormap does?

Re: Team shirt colors

Posted: Wed Mar 14, 2012 10:06 pm
by mankrip
FrikBot does all kinds of checks like these, iirc you can even choose which team a bot should belong to. Its source code probably has all you need.

Re: Team shirt colors

Posted: Wed Mar 14, 2012 10:33 pm
by Cobalt
Yea, probably right. Has he stopped developing Frikbot? I dont have any of the src's for that mod at all. Checked the usual spot /frikbot , but cant find a dl link......

mankrip wrote:FrikBot does all kinds of checks like these, iirc you can even choose which team a bot should belong to. Its source code probably has all you need.

Re: Team shirt colors

Posted: Thu Mar 15, 2012 6:03 am
by Cobalt
Ok, heres what I came up with so far, kinda primitive, but works ' decent ' :

Code: Select all


float (float t, entity ent) TeamGetShirt =
{

local float x;


if ((t == TEAM_COLOR1))
{
do
			{
				x = (rint (random () * 15) + 1);
				if (x == 14) // illegal shirt color
				{
				if (random () < 0.5)
				x = (rint (random ()) + 15);
				else
				x = (rint (random () * 12) + 1);
				}
				
				

			} while ((team1shirt & x));
                      team1shirt = team1shirt | x - 1;
			 return x - 1;

}

if ((t == TEAM_COLOR2))
{
do
			{

                            x = (rint (random () * 15) + 1);
				if (x == 4) // illegal shirt color
				{
				if (random () < 0.5)
				x = (rint (random () * 11) + 5);
				else
				x = (rint (random () * 3));
				}			

			} while ((team2shirt & x));
                      team2shirt = team2shirt | x - 1;
			 return x - 1;

}


 

What I dont like is the team_shirt & x part, as it seems to allow duplicates of color 0 alot. My original plan was to float out values for shirt0 through shirt15 as global floats by bitflagging them all up to 32768 which would represent shirt 15. then I guess I would have to paste them all out again in another sub that is called within this code and bitflag them in. I am surprised that this code worked as well as it did.

Re: Team shirt colors

Posted: Thu Mar 15, 2012 4:59 pm
by mankrip
Cobalt wrote:I dont have any of the src's for that mod at all. Checked the usual spot /frikbot , but cant find a dl link......
Here.

Re: Team shirt colors

Posted: Thu Mar 15, 2012 5:45 pm
by r00k
I thought .colormap in stock quake was just the client slot number like when you type status online.

heres a bit of code for ya

Code: Select all

void(entity ent, float clientshirt, float clientpants) setcolor =
{
	local float client;

	client = (ent.colormap - 1);

	msg_entity = ent;
	WriteByte (MSG_ALL, SVC_UPDATECOLORS);
	WriteByte (MSG_ALL, client);
	WriteByte (MSG_ALL, ((clientshirt * 16) + clientpants));
};
in proquake (which wont be viable on stock quake)

Code: Select all

float () get_top_color =
{
	local float tc;

	tc = floor((self.cl[CL_COLORS] / %1) / 16);

	return tc;
};

Re: Team shirt colors

Posted: Fri Mar 16, 2012 4:57 am
by Cobalt
Yes, you are right...its represents that number, I call it a slot number....but not sure if that is a good term for it. Thought it does something for the colors of the player, but cant confirm yet. In Darkplaces lets say your shirt is 4 (red) and you throw an ammo backpack via an impulse. If you set its .colormap to your colormap, the pack turns the color of your shirt (4).

They are also using this:

self.clientcolors = 12 * 16 + 4; // yellow (12) shirt and red (4) pants

...to I guess show the correct color in the scoreboard, which is likely internally identical to that writemessage code you posted.

I messed with my code today, and bitflagged out those floats like I intended, wrote a new bitflag check routine, and found some more illegal colors for the shirts. It was doing an endless loop until I saw I was not setting those team shirt floats to a non zero number, and when you check bitflags like that, the while-do loop was always seeing them as NOT or Zero! So I decided to check them for that first....then return a legal value and also set the float to a non zero so it would not fail the loop next time its picking a color for a client. Not sure if it can be done simpler or not, but so far seems to do the trick.


Code: Select all


float shirt1 = 1; // shirt color 0
float shirt2 = 2; // color 1
float shirt3 = 4;
float shirt4 = 8;
float shirt5 = 16;
float shirt6 = 32;
float shirt7 = 64;
float shirt8 = 128;
float shirt9 = 256;
float shirt10 = 512;
float shirt11 = 1024;
float shirt12 = 2048
float shirt13 = 4096;
float shirt14 = 8192;
float shirt15 = 16384;
float shirt16 = 32768; // color 15







float (float r) MatchBitflag =

{

if (!r)
return shirt1; 
if (r == 1)
return shirt2; 
if (r == 2)
return shirt3; 
if (r == 3)
return shirt4; 
if (r == 4)
return shirt5; 
if (r == 5)
return shirt6; 
if (r == 6)
return shirt7; 
if (r == 7)
return shirt8; 
if (r == 8)
return shirt9; 
if (r == 9)
return shirt10; 
if (r == 10)
return shirt11; 
if (r == 11)
return shirt12; 
if (r == 12)
return shirt13; 
if (r == 13)
return shirt14; 
if (r == 14)
return shirt15; 
if (r == 15)
return shirt16;  
};





float (float t, entity ent) TeamGetShirt =
{

local float x,v;


if ((t == TEAM_COLOR1))
{
if (!team1shirt)
{
 x = (rint (random () * 12));
 v = MatchBitflag (x + 1); // Illegal composite function
  team1shirt = team1shirt | (v);
return x;
}
do
			{
				x = (rint (random () * 15) + 1);
				if (x == 14 || x == 15)
				{
				if (random () < 0.5)
				x = 16;
				else
				x = (rint (random () * 13));
				}
				if (x - 1 < 0) // Illegal composite function
				x = 0;
				if (!team1shirt)
				 return (x - 1); // Illegal composite function
				v = MatchBitflag (x);

			} while ((team1shirt & v));
                      team1shirt = team1shirt | (v);
			 return (x - 1); // Illegal composite function

}

if ((t == TEAM_COLOR2))
{

if (!team2shirt)
{
x = (rint (random () * 10) + 5) ;
v = MatchBitflag (x + 1); // Illegal composite function
team2shirt = team2shirt | (v);
return x;
 }

do
			{

                            x = (rint (random () * 15) + 1);
				if (x == 4 || x == 5)
				{
				if (random () < 0.5)
				x = (rint (random () * 11) + 5);
				else
				x = (rint (random () * 2));
				}			
				if (x - 1 < 0) // Illegal composite function
				x = 0;
				
				
				v = MatchBitflag (x);
				
			} while ((team2shirt & v));
                      team2shirt = team2shirt | (v);
			 return (x - 1); // Illegal composite function

}



};






Also added some code in setchangeparms() and decodelevelparms() that floats those globals to scratch1 and scratch2 cvars so that they are known
between level changes. Next I need to set a clients bitflag free when they disconnect or go observer.

Also noticed that in Darkplaces, shirtcolor 15 appears as a bright fire orange color in the scoreboard, and the players shirt in the game looks light lime green. I thought maybe darkplaces added more colors..so am checking with LH on that one, strange.....


EDIT / UPDATE:

Found out this code would not work because it uses some ' composite functions ' that are illegal in QC. However most compilers out there wont detect them. I commented my bad code and updated this post today.


r00k wrote:I thought .colormap in stock quake was just the client slot number like when you type status online.

Re: Team shirt colors

Posted: Sat Mar 17, 2012 8:53 pm
by Cobalt
Ok, I edited my above post because I am pretty sure I used composite functions that would send attempted passed values into ' limbo' somewhere.
I have discovered that the smallest violation of this rule gives really unpredictable results that are impossible to trace logicly, because your passed values go absolutely nowhere to be found. I have commented those lines of code for anyones input on the matter. The compiler I am using is FrikQcc, and I acknowledge that other compilers may warn or disallow these coding practices, possibly.

Also seems I dont need to use " | " to merge the bitfield into the shirtcolor team floats...merely adding and subtracting them as their bitflag corresponding floats is in effect doing the same thing. The new code seems to be working alot better overall :
(we use the same global floats as previous code )

Code: Select all



loat (float t, entity ent) TeamGetShirt =
{

local float x,v,h;


if ((t == TEAM_COLOR1))
{
if (!team1shirt)
{

 x = (rint (random () * 12));
 h = x + 1;
 v = MatchBitflag (h);
  team1shirt = v;
return x;
}
do
			{
				x = (rint (random () * 15) + 1);
				if (x == 14 || x == 15)
				{
				if (random () < 0.5)
				x = 16;
				else
				x = (rint (random () * 12));
				}
				h = x - 1;
				if (h < 0)
				x = 0;
				
				 
				v = MatchBitflag (x);

			} while ((team1shirt & v));
			team1shirt = (team1shirt + v);
			 return (h);

}

if ((t == TEAM_COLOR2))
{

if (!team2shirt)
{
x = (rint (random () * 10) + 5) ;
h = x + 1;
v = MatchBitflag (h);
team2shirt = v;
return x;
 }

do
			{

                            x = (rint (random () * 15) + 1);
				if (x == 4 || x == 5)
				{
				if (random () < 0.5)
				x = (rint (random () * 11) + 5);
				else
				x = (rint (random () * 2));
				}			
				
				h = x - 1;
				if (h < 0)
				h = 0;
				
				v = MatchBitflag (x);
				
			} while ((team2shirt & v));
                      team2shirt = (team2shirt + v);
			 return (h);

}


// Called when player goes observer or disconnects
void () ReleaseShirtColor =

{
if (!self.clientcolors) return; // we are observer already , colors 0 0
bprint ("gonna free up your shirtcolor : ");
bprint (ftos(self.shirt_color));
bprint ("\n");
self.shirt_color = self.shirt_color + 1;
local float v;
v = MatchBitflag (self.shirt_color);

bprint (" >> which is matchshirt bitmap : ");
bprint (ftos(v));
bprint ("\n");
if (self.team == 14)
{
team2shirt = (team2shirt - v);
bprint ("NEW TEAM2SHIRT : ");
bprint (ftos(team2shirt));
bprint ("\n");
}
if (self.team == 5)
{
team1shirt = (team1shirt - v);
bprint ("New TEAM1SHIRT : ");
bprint (ftos(team1shirt));
bprint ("\n");
}

};




};




Re: Team shirt colors

Posted: Mon Mar 19, 2012 8:56 pm
by LordHavoc
r00k: DP_SV_SETCOLOR extension is your friend, allowing both intercepting of color changes by clients and rejection and replacement of those, as well as just outright setting someone's color at any time - and you don't need to re-send all those svc_updatecolor messages when someone joins mid-game.

DP_SV_CLIENTCOLORS is fun too.

Re: Team shirt colors

Posted: Mon Mar 19, 2012 10:09 pm
by r00k
Thanks LH, i'll check those out...