Author |
Message |
ThunderJam Newbie
Joined: Feb 04 2006 Posts: 15 Offline
|
Posted: Fri Apr 25, 2008 7:02 pm Post subject: merv kill() in linkedlists |
|
|
|
|
Ok in this plugin im maintaining a linkedlist of players that are within a certain area on the map.
in playermove event i check if they are outside of the area, then if they WERE within the linkedlist. If so, they WERE in it, but just moved out of the area, so i need to remove them from the linkedlist.
Looked up the linkedlist functions that merv provides, and doing kill(player) throws a popup debug error from my mervbot!!!
Anyone know anythign abotu this? |
|
Back to top |
|
|
ThunderJam Newbie
Joined: Feb 04 2006 Posts: 15 Offline
|
Posted: Fri Apr 25, 2008 7:58 pm Post subject: |
|
|
|
|
More info:
im running msvc 6.0
The error message pertains to some dbsomething.c file that is not part of the merv source files i dont think
i donno what the heck is going on :/ |
|
Back to top |
|
|
Bak ?ls -s 0 in
Age:25 Gender: Joined: Jun 11 2004 Posts: 1826 Location: USA Offline
|
|
Back to top |
|
|
ThunderJam Newbie
Joined: Feb 04 2006 Posts: 15 Offline
|
Posted: Fri Apr 25, 2008 9:29 pm Post subject: |
|
|
|
|
The problem occurs where i do kill(p) on either of the linkedlists
case EVENT_PlayerMove:
{
Player *p = (Player*)event.p[0];
if(inHill(p)) {
if(p->team==0) {
if(team0Players.find(p) == NULL) {
team0Players.append(p);
sendPublic("player entered hill");
}
}
else if(p->team==1) {
if(team1Players.find(p) == NULL) {
team1Players.append(p);
sendPublic("player entered hill");
}
}
}
else { //if not in hill
if(p->team==0 && team0Players.find(p)!=NULL) {
sendPublic("player left hill");
team0Players.kill(p);
}
else if(p->team==1 && team1Players.find(p)!=NULL) {
sendPublic("player left hill");
team1Players.kill(p);
}
}
}
|
and heres the linkedlists declarations:
_linkedlist <Player> team0Players; //team 0 players in the hill
_linkedlist <Player> team1Players; //team 1 players in the hill
|
|
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Sat Apr 26, 2008 1:40 am Post subject: |
|
|
|
|
oh...
The problem is:
when you call 'kill', it scrolls through the list, finds the pointer to the item, and DELETES the data. ie it doesn't only clear it from the list, it also deletes the original Player struct created by the bot. So from that point, the bot is screwed up because it cleared memory that it was still using. If you check the code of the .kill() method, you'll find a 'delete' statement that does exactly that.
There are 4 possible solutions that I can think of:
The first one can be guessed by checking the .kill() method, you'll find a 'if (copy)' or something (from memory). So you can set the copy value to true before killing. However, this solution sucks cause 'copy' is set back to false at a couple of places in the code.
The second solution is to use .unlist(p) instead of kill. As the name says, it only unlists the item, without deleting the original struct. If you check the code, you'll see that it actually sets copy to false, then calls the kill() method. So it's pretty much like solution #1, except easier. You have to watch out when you clear the list though... Not sure if there's a method to clear it without killing original structs, or if you need to unlist them all ... anyway you'll figure it out.
The third solution is to make a list of 'Player *' instead of a list of 'Player'. This makes a lot of things more complicated in the code though...
The fourth solution, the one that I always use, is to create your own PlayerData struct or class. Your own class could hold information like kills, deaths, and goals, or whatever stats you want. And you'd have a name field so you can find a specific player in your list.
This solution allows you to keep stats of players even after they left the game. And their stats can stay if they come back a few seconds later. You can do pretty much anything you want, and you don't have to worry about affecting the original data. If you're using a lot of tags for different data, this method also makes it more efficient cause everything is at the same place. You just have to handle the players coming in and out of the arena correctly.
If you don't have to get any more complicated than what you have there, simply using .unlist(p) would work fine I think. But if you want to keep track of more things, managing a list of your own struct could be a good option.
I hope that (long) post helped... kind of tired, so if anything is not clear... well... TOO BAD >=) _________________ (Insert a bunch of dead links here) |
|
Back to top |
|
|
Bak ?ls -s 0 in
Age:25 Gender: Joined: Jun 11 2004 Posts: 1826 Location: USA Offline
|
|
Back to top |
|
|
ThunderJam Newbie
Joined: Feb 04 2006 Posts: 15 Offline
|
Posted: Sat Apr 26, 2008 10:01 am Post subject: |
|
|
|
|
*bows down to sama* |
|
Back to top |
|
|
Samapico No, these DO NOT look like penises, ok?
Joined: May 08 2003 Posts: 1252 Offline
|
Posted: Sat Apr 26, 2008 11:05 am Post subject: |
|
|
|
|
Bak wrote: | arg, I forgot to look in the listnode destructor... good find samp (i guess this is why people hate c++). Looks like when you declare the linkedlist initializing it with true will prevent it from freeing the Players
_linkedlist <Player> team0Players(true); //team 0 players in the hill
_linkedlist <Player> team1Players(true); //team 1 players in the hill |
| Yeah that should work too... if you do that, however, don't use the unlist anywhere, cause:
TEMPLATE void _linkedlist <AnonymousStruct>::unlist(AnonymousStruct *item)
{
copy = true;
kill(item);
copy = false;
}
|
For some reason it resets it to false, whatever it was set to before... |
|
Back to top |
|
|
|