Forum

"You've got the lead"

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

"You've got the lead"

Postby redrum » Wed Nov 14, 2007 4:41 am

How can I get a message to print:
"You've got the lead" when you take the lead in DM?
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 » Wed Nov 14, 2007 7:29 am

First look inside the ClientObituary() function. Notice all the instances where .frags is added to or subtracted from. I think the easiest method, considering the current setup of the function, would be to replace each of the instances, where .frag is manipulated, with something like Frag(ent, 1) or Frag(ent, -1). Then you would need to make the actual function that you're calling, which would look something like:

Code: Select all
void(entity ent, float amount)Frag =
{
   local entity oldleader;
   oldleader = leader;
   ent.frags = ent.frags + amount;

   // if you're not in deathmatch, end the function here
   if(!deathmatch)
      return;

   // since losing frags may bump someone besides ent into the lead you'll want to check all the players' frags
   head = nextent(world);
   while(head)
   {
      if(head.frags > leader.frags)
         leader = head;
      head = nextent(head);
   }

   if(leader != oldleader)
      sprint(leader, "You've got the lead.\n");
};

You'll also have to create a global entity to point to the current leader, hence the "leader" variable used above.
Last edited by daemon on Thu Nov 15, 2007 3:25 am, edited 1 time in total.
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Wed Nov 14, 2007 5:21 pm

so then how would I change this line?
Code: Select all
            logfrag (attacker, targ);
            attacker.frags = attacker.frags + 1;


and this?
Code: Select all
      if (attacker.classname == "teledeath")
      {
         bprint (PRINT_MEDIUM,targ.netname);
         bprint (PRINT_MEDIUM," was telefragged by ");
         bprint (PRINT_MEDIUM,attacker.owner.netname);
         bprint (PRINT_MEDIUM,"\n");
         logfrag (attacker.owner, targ);

         attacker.owner.frags = attacker.owner.frags + 1;
         return;
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 » Wed Nov 14, 2007 5:34 pm

Ah, we're using different codebases, but that doesn't matter. Just replace those lines where .frags is added with Frag(ent, amount);

ent being attacker or attacker.owner, and frags being the amount of course.

I also just noticed you lose some frags in ClientKill(), so you might want to change the line where the 2 frags are subtracted to call the Frag() function instead. Frag(self, -2);
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Wed Nov 14, 2007 10:32 pm

So it would look like this?
Code: Select all
      if (attacker.classname == "teledeath")
      {
         bprint (PRINT_MEDIUM,targ.netname);
         bprint (PRINT_MEDIUM," was telefragged by ");
         bprint (PRINT_MEDIUM,attacker.owner.netname);
         bprint (PRINT_MEDIUM,"\n");
         logfrag (attacker.owner, targ);

         Frag(attacker.owner) = Frag(attacker.owner, +1);
         return;
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 Entar » Wed Nov 14, 2007 11:04 pm

No, I think it would be just...
Code: Select all
Frag(attacker.owner, 1);
User avatar
Entar
 
Posts: 439
Joined: Fri Nov 05, 2004 7:27 pm
Location: At my computer

Postby redrum » Wed Nov 14, 2007 11:09 pm

Aha! Thanks Entar. I knew I was *#$@*!ing something up!
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 redrum » Thu Nov 15, 2007 1:14 am

Works great!
Entar, can you please explain in laymans terms how the code works.
It would help me to learn. Thanks.
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 Entar » Thu Nov 15, 2007 4:25 am

Code: Select all
void(entity ent, float amount)Frag =
{
   local entity oldleader;
   oldleader = leader;
   ent.frags = ent.frags + amount;

   // if you're not in deathmatch, end the function here
   if(!deathmatch)
      return;

   // since losing frags may bump someone besides ent into the lead you'll want to check all the players' frags
   head = nextent(world);
   while(head)
   {
      if(head.frags > leader.frags)
         leader = head;
      head = nextent(head);
   }

   if(leader != oldleader)
      sprint(leader, "You've got the lead.\n");
};

First line is a new entity variable declaration, and the next one sets that variable to be the the one that's currently leading. It then increments the killer's frag count. Check if you're in deathmatch, and if not, stop, because that's the only place where you would be in the lead. It then cycles through the other players and checks who is in the leading, and if it's different from who it thought, then it tells the leader that he's in the lead now.
User avatar
Entar
 
Posts: 439
Joined: Fri Nov 05, 2004 7:27 pm
Location: At my computer

Postby daemon » Thu Nov 15, 2007 6:46 am

you could also move the first two lines below the deathmatch check to make the code slightly more effecient.

redrum: is there any specific part of that code you'd like explained in more detail?
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Postby redrum » Thu Nov 15, 2007 3:46 pm

I don't understand "head" and "nextent".

Also, you can just make up your own entities?

Let me try to understand this:

void(entity ent, float amount)Frag = //NEW FUNCTION
{
local entity oldleader; //NEWLY CREATED ENTITY
oldleader = leader; //LEADER IS STILL THE LEADER???
ent.frags = ent.frags + amount; //WHICH ENTITY GETS THE FRAGS

// if you're not in deathmatch, end the function here
if(!deathmatch) //EZ ENOUGH
return;

// since losing frags may bump someone besides ent into the lead you'll want to check all the players' frags
head = nextent(world); //?????
while(head) //?????
{
if(head.frags > leader.frags) //?????
leader = head; //?????
head = nextent(head); //?????
}

if(leader != oldleader) //NEW LEADER
sprint(leader, "You've got the lead.\n"); //EZ ENOUGH
};
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 » Thu Nov 15, 2007 4:23 pm

As a general note, if you don't run the function spawn() then you don't actually create a new entity on the server. The only new things created here are variables which have a particular entity's "number" stored in them, and allow you to access that entity. (The technical term is a "pointer" to the entity).

Code: Select all
void(entity ent, float amount)Frag =
{
   local entity oldleader;//this creates a new variable that stores an entitiy

   oldleader = leader; //we're going to store which entity was the leader before this frag was scored in our new variable
   ent.frags = ent.frags + amount; //now we add the score to the entity stored in ent, which was sent from the calling function
//so if the calling function had the line
// Frag(self, 1);
// then the entity self would gain the frag, because the first parameter of the function gets called ent here
// look at the very first line of this function for details

   // if you're not in deathmatch, end the function here
   if(!deathmatch)
      return;

   head = nextent(world);//head is just another entity variable, like oldentity was
//we don't need to define a local head, because it is a global variable we can use for temporary storage.

//the function nextent counts through the list of entites in the server in order, so if you send it an entity then it returns the next one.
//If you read the last entity of a list it returns the world entity, which is always #0 on the list.

   while(head) //this is shorthand for while(head != world), meaning we've not reached the end of the list.
   {
      if(head.frags > leader.frags) //if the entity we just pulled from the server list and stored in head has more frags than the entity in the leader variable
         leader = head; //then store that entity in leader instead
      head = nextent(head);//now pull the next entity from the list and go round the loop again if we haven't reached the end.
   }

//at the end of this loop, the variable "leader" will store the entity with the most frags

   if(leader != oldleader) //we can now see if the leader is the same as the old leader
      sprint(leader, "You've got the lead.\n"); //if it isn't, send a message to the new one.
};


I was going to suggest that as an exercise, you tell me what line you should add to send a message saying "You've lost the lead!" to the code. The problem is, doing that will expose a server-stopping bug, which can also occur in the current code. So there's three open questions on offer:
1) What's the obvious line to add to do that?
2) Why would the obvious line cause a server crash on the first frag, and how can it be avoided?
(nb, maybe it doesn't happen with the world entity, I forget)
3) How can the same crash occur with the current code?
Preach
 
Posts: 122
Joined: Thu Nov 25, 2004 7:20 pm

Postby daemon » Thu Nov 15, 2007 4:40 pm

it wouldn't crash in DP, but you would definatly get an error message. good point. I'll see if anyone else can spot this :)
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

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

It seems to be easy.
I would add this.
Code: Select all
sprint(oldleader, "You lost the lead!\n");

below
Code: Select all
sprint(leader, "You've got the lead!\n");

That should work right?
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 3:30 am

correct, but since the if() leads to more than one line, don't forget the brackets.

now on to questions 2 and 3
-daemon [ daemonforge.org ]
User avatar
daemon
 
Posts: 63
Joined: Wed Nov 07, 2007 11:10 pm

Next

Return to QuakeC Programming

Who is online

Users browsing this forum: Bing [Bot] and 1 guest