Forum

"You've got the lead"

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Postby redrum » Fri Nov 16, 2007 3:54 am

I guess there would be no oldleader at the time of the first frag.
So, I guess, we can put this somewhere:

Code: Select all
self = oldleader;


So everyone who starts the game would be the "oldleader"?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby daemon » Fri Nov 16, 2007 4:45 am

oldleader is a local entity created each time the function spawns, defaulting to world, then once set by "oldleader = leader" oldleader will be the current leader. the global entity, leader, defaults to world at the begenning of the game, and when the function is called and leader is world, oldleader will also end up as world. this causes no problem UNLESS you try to sprint to oldleader while it is a non-client. since world isn't a client, it will cause an error while there is no leader before the function is called.

ultimately you'll want to check somewhere if the entity you're either looking at or trying to sprint to is a client or not. this can be done a few different ways:

Code: Select all
if(entity.classname == "player")

or
Code: Select all
if(entity.flags & FL_CLIENT)


I would use the 2nd method if doing any checks inside loops for speed purposes, but I always like to use floats instead of strings when possible because strings can be rather slow at times.

self = oldleader;

that would set self to whichever entity oldleader is pointing to, and since self is always the entity that is looking at the code, there would be no reason to do that in this situation.

but once you understand all of this, question 3 still remains:

3) How can the same crash occur with the current code?
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Fri Nov 16, 2007 4:57 am

I kinda understand but not fully.
Maybe it would happen if a player left the game while being the leader?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby daemon » Fri Nov 16, 2007 5:45 am

look more closely at this part of the function, noting that all entities are being looked at here, not just players.

Code: Select all
   head = nextent(world);
   while(head)
   {
      if(head.frags > leader.frags)
         leader = head;
      head = nextent(head);
   }


then this part, remembering that sprinting to a non-client results in an error.

Code: Select all
sprint(leader, "You've got the lead.\n");
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Fri Nov 16, 2007 4:58 pm

Wouldn't only clients acquire frags though?
So how would a non-client become "leader"?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Preach » Fri Nov 16, 2007 5:26 pm

redrum wrote:Wouldn't only clients acquire frags though?
So how would a non-client become "leader"?


Ah, that's the cunning part. If you suicide you lose frags, so it's possible for all the players on the map to have < 0 frags. Then something else on the map, which starts with 0 frags, would take the lead. You wouldn't have to worry about this if players can only gain frags.
Preach
 
Posts: 122
Joined: Thu Nov 25, 2004 7:20 pm

Postby redrum » Fri Nov 16, 2007 7:33 pm

I see.
I did notice in my mod that when I am -5, and someone is -7 that I am not the leader. But it doesn't crash though. So I guess it's ok.
I would like it to work in the negative numbers though.
Where should I put
Code: Select all
if(entity.classname == "player")

for it to work?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby daemon » Fri Nov 16, 2007 9:13 pm

yes, or the non-string version:

Code: Select all
if(entity.flags & FL_CLIENT)

but where would you put it?

also remember, using strings in loops can be very slow.
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Fri Nov 16, 2007 9:50 pm

Code: Select all
   if(leader != oldleader && oldleader.flags & FL_CLIENT && leader.flags & FL_CLIENT)
       {
       centerprint(leader, "You've got the lead!\n");
       centerprint(oldleader, "You've lost the lead!\n");
       }

Hows that?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby daemon » Sat Nov 17, 2007 2:52 am

that would prevent anything being printed to the leader or oldleader if EITHER of them aren't clients, which is almost right for part of it.

The first thing you want to do is prevent leader from being set to anything that isn't a client in the loop above that, BUT the first time the function is called, oldleader will still == world, SO, what you need to do is also put an if() statement just above the line that prints to the oldleader.
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby daemon » Sat Nov 17, 2007 10:00 pm

another exercise would be to make it check for ties, and then if so sprint to everyone who is tied for the lead instead of sprinting to leader and oldleader.
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Sun Nov 18, 2007 9:20 pm

Code: Select all
if(leader != oldleader && oldleader.flags & FL_CLIENT && leader.flags & FL_CLIENT)

Let me see if I understand this line of code.
It means if the leader is not the oldleader and the oldleader is a client and the leader is a client?

Let's try the exercise.
Code: Select all
if (leader.frags == oldleader.frags)
   {
   bprint (PRINT_MEDIUM,leader.netname);
   bprint (PRINT_MEDIUM,oldleader.netname);
   bprint (PRINT_MEDIUM, " are tied for the lead");
   }
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Sun Nov 18, 2007 9:35 pm

And notice these lines:

Code: Select all
bprint (PRINT_MEDIUM,leader.netname);
bprint (PRINT_MEDIUM,oldleader.netname);
bprint (PRINT_MEDIUM, " are tied for the lead");


You should put something between the first two and put a \n after the last letter of the last line, otherwise the in-game string will be like this:

Code: Select all
player1player2 are tied for the leadSome other sprint...



Use this instead:

Code: Select all
if (leader.frags == oldleader.frags)
   {
   bprint (PRINT_MEDIUM,leader.netname);
   bprint (PRINT_MEDIUM, " and ");
   bprint (PRINT_MEDIUM,oldleader.netname);
   bprint (PRINT_MEDIUM, " are tied for the lead\n");
   }


And that's it.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

Postby redrum » Mon Nov 19, 2007 12:28 am

I tested it, this does the trick!
if (ent.frags == leader.frags && ent != leader)
Code: Select all
   {
   bprint (PRINT_MEDIUM,leader.netname);
   bprint (PRINT_MEDIUM, " and ");
   bprint (PRINT_MEDIUM,ent.netname);
   bprint (PRINT_MEDIUM, " are tied for the lead\n");
   }

What if 3 players are tied though :?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Orion » Mon Nov 19, 2007 12:50 am

Well, not just 3, but 4, 5, 6, 7, or 1654984156 players can be tied. But anyways, it's not hard to do that.

NOTE: My code might not work correctly, because I'm doing from scratch without testing.


Well, let's see...
You should create a local entity and do a find().
Then check if more than 2 players are tied, and then, bprint correctly.

Try this:

Code: Select all
local entity t;

bprint (PRINT_MEDIUM,leader.netname);
bprint (PRINT_MEDIUM,", ");

t = find(world, classname, "player");
while (t != world)
{
   if (t.frags == leader.frags && t != leader)
   {
      bprint (PRINT_MEDIUM,t.netname);
      bprint (PRINT_MEDIUM,", ");
        }
   t = find(t, classname, "player");
}

bprint (PRINT_MEDIUM," are tied for the lead\n");


Give it a try... maybe it works.
User avatar
Orion
 
Posts: 476
Joined: Fri Jan 12, 2007 6:32 pm
Location: Brazil

PreviousNext

Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest