Need help

Discuss programming in the QuakeC language.
Post Reply
Orion
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Need help

Post by Orion »

Hi.. I've made a teamplay just like clan arena, and I need some help.

I've create global floats for how much member of blue and red team, and globals on how much dead blue and red members.

When all enemies are dead, it should kill everybody and respawn'em, but it isn't working! :(

Take a look, the function is handled by PlayerPreThink():

Code: Select all

void() LookForOthers =
{
	local entity head;
	
	if (members_team1 == 0 || members_team2 == 0)
		return;
	
	head = find(world, classname, "player");
	while (head != world)
	{
		if (team1_dead == members_team1 || team2_dead == members_team2)
		{
			head.health = 100;
			head.takedamage = DAMAGE_AIM;
			T_Damage (head, world, world, 100);
			head.died = 0;
			team1_dead = 0;
			team2_dead = 0;
			if (!head.human)
			{
				head.fShirt = head.oshirt;
				head.fPants = head.opants;
				msgUpdateColorsToAll (head.fClientNo, head.fShirt, head.fPants);
			}
		}
		
		head = find(head, classname, "player");
	}
};
What's wrong here?

Thanks...
Electro
Posts: 312
Joined: Wed Dec 29, 2004 11:25 pm
Location: Brisbane, Australia
Contact:

Post by Electro »

Code: Select all

while (head != world) 
this can be reduced to merely

Code: Select all

while(head)
as the while loop will only be done if a player is found anyway


I assume you're functions for setting members_team1 and members_team2 are correct and being called before this function, right?

Code: Select all

if (team1_dead == members_team1 || team2_dead == members_team2) 
What's this doing exactly? I think you need to break down the logic at which you're handling things. This is meant to be checking if all players on either side are dead, correct?

I would move this line out of the while loop and up to the top of the function just like you're checking for members_team1 and members_team2.

This would speed things up because it wouldn't bother searching through every player every frame unless the count of dead players counts up to the total number of players for that team.

How are you counting up the team1_dead and team2_dead numbers?

You'll need to post a bit more info, as I think the problem is also part of something else that you haven't shown.

Additionally, I think the respawning of all the players should be handled automatically too rather than just killing everyone.

So something along the lines of

Code: Select all

oself = self;
self = head;
PutClientInServer();
head = oself;
I will be happy to help you out more once you post some more info :)
Benjamin Darling
http://www.bendarling.net/

Reflex - In development competitive arena fps combining modern tech with the speed, precision and freedom of 90's shooters.
http://www.reflexfps.net/
Orion
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Post by Orion »

Well, I've added a specific deathmatch and teamplay cvar for playing it too.

At PutClientInServer() I've put the default player's team (blue) when deathmatch is set to 6.

It looks like this:

Code: Select all

self.team_no = 1;
members_team1 = members_team1 + 1;
At weapons.qc I've added an impulse to change the team:

Code: Select all

void() ChangeTeam =
{
	if (self.team_no == 1)
	{
		self.team_no = 2;
		members_team1 = members_team1 - 1;
		members_team2 = members_team2 + 1;
	}
	else
	{
		self.team_no = 1;
		members_team2 = members_team2 - 1;
		members_team1 = members_team1 + 1;
	}
};
At player.qc, PlayerDie() I've added this at the very top:

Code: Select all

self.died = 1;
if (self.team_no == 1)
	team1_dead = team1_dead + 1;
else
	team2_dead = team2_dead + 1;
self.died = 1 will make the player respawn as an observer, non-solid, but visible.

At PlayerPreThink() in client.qc there's some code I've added:

Code: Select all

if (self.died)
	stuffcmd (self, "color 0\n");
else
{
	if (self.team_no == 1)
		stuffcmd (self, "color 13\n");
	else
		stuffcmd (self, "color 4\n");
}
Electro
Posts: 312
Joined: Wed Dec 29, 2004 11:25 pm
Location: Brisbane, Australia
Contact:

Post by Electro »

If my memory serves me right, doing stuffcmd per frame is bad :(
How would you like commands stuffed onto you per frame! hehe

PutClientInServer() is called every time somebody respawns, so by doing members_team1 = members_team1 + 1; there, your game is thinking more and more people are joining :o

I think you're best off just doing a find per frame (easiest way) to tally up all the players.

Due to not wanting to do it per frame you're best off creating a 'manager' entity. This entity would then be responsible for handling things like this and you can just do it on that entity without worry about doing it per player per frame, just once for the manage entity per frame (or however often you choose).

To count up all the players per team would be easy, you can even count how many in the game total.

Code: Select all

float members_team1, members_team2, members_total;

void() CountPlayers =
{
      local entity e;

      members_team1 = members_team2 = members_total = 0;

      while(e)
      {
            if (e.team_no == 1)
                  members_team1 = members_team1 + 1;
            if (e.team_no == 2)
                  members_team2 = members_team2 + 1;
            members_total = members_total + 1;

            e = find(e, classname, "player");
      }
      self.nextthink = time + 1; // only use this if you do the manager thingy!
};
Ok now that's all your things accurately set, you would NOT to do this in PlayerPreThink as it'd be done per player per frame OUCH


Ok for doing the manager style entity, in StarFrame i'd do something like...

Code: Select all

if (!manager_ent) // manager doesn't exist, create it
{
      manager_ent = spawn();
      manager.think = CountPlayers();
      manager.nextthink = time + 1;
}

obviously throw

Code: Select all

entity manager_ent;
in defs or something.


The benefit of having the manager is you can obviously do more things than just this in a think, you could make the .think a ManagerUpdate or something, and then have a bunch of functions like counting players, checking for dead/alive players etc. per frame only once, rather than per player per frame.

It's basically how things were handled on Pro-X vaguely.

If this stuff doesn't work properly or there's typos, sorry I've done all this just in the enter message dialog on the forum and haven't actually tried any of this. ;)

Oh... and because you would already be searching through all the players in CountPlayers, you might as well count up all the ones that are dead/alive there too, and get everything over with in 1 hit ;)

Good luck! keep posting as much as you need to :D
Benjamin Darling
http://www.bendarling.net/

Reflex - In development competitive arena fps combining modern tech with the speed, precision and freedom of 90's shooters.
http://www.reflexfps.net/
Post Reply