Crossfire Server, Branch 1.12  R12190
friend.c
Go to the documentation of this file.
00001 /*
00002  * static char *rcsid_friend_c =
00003  *   "$Id: friend.c 11578 2009-02-23 22:02:27Z lalo $";
00004  */
00005 
00006 /*
00007     CrossFire, A Multiplayer game for X-windows
00008 
00009     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
00010     Copyright (C) 1992 Frank Tore Johansen
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025 
00026     The authors can be reached via e-mail at crossfire-devel@real-time.com
00027 */
00028 
00034 #include <global.h>
00035 
00043 void add_friendly_object(object *op) {
00044     objectlink *ol;
00045 
00046     /* Add some error checking.  This shouldn't happen, but the friendly
00047      * object list usually isn't very long, and remove_friendly_object
00048      * won't remove it either.  Plus, it is easier to put a breakpoint in
00049      * the debugger here and see where the problem is happening.
00050      */
00051     if (is_friendly(op)) {
00052         LOG(llevError, "add_friendly_object: Trying to add object already on list (%s)\n", op->name);
00053         return;
00054     }
00055 
00056     ol = first_friendly_object;
00057     first_friendly_object = get_objectlink();
00058     first_friendly_object->ob = op;
00059     first_friendly_object->id = op->count;
00060     first_friendly_object->next = ol;
00061 }
00062 
00069 void remove_friendly_object(object *op) {
00070     objectlink *this;
00071 
00072     CLEAR_FLAG(op, FLAG_FRIENDLY);
00073 
00074     if (!first_friendly_object) {
00075         LOG(llevError, "remove_friendly_object called with empty friendly list, remove ob=%s\n", op->name);
00076         return;
00077     }
00078     /* if the first object happens to be the one, processing is pretty
00079      * easy.
00080      */
00081     if (first_friendly_object->ob == op) {
00082         this = first_friendly_object;
00083         first_friendly_object = this->next;
00084         free(this);
00085     } else {
00086         objectlink *prev = first_friendly_object;
00087 
00088         for (this = first_friendly_object->next; this != NULL; this = this->next) {
00089             if (this->ob == op)
00090                 break;
00091             prev = this;
00092         }
00093         if (this) {
00094             /* This should not happen.  But if it does, presumably the
00095              * call to remove it is still valid.
00096              */
00097             if (this->id != op->count) {
00098                 LOG(llevError, "remove_friendly_object, tags do no match, %s, %d != %d\n",
00099                     op->name ? op->name : "none", op->count, this->id);
00100             }
00101             prev->next = this->next;
00102             free(this);
00103         }
00104     }
00105 }
00106 
00113 void dump_friendly_objects(void) {
00114     objectlink *ol;
00115 
00116     for (ol = first_friendly_object; ol != NULL; ol = ol->next)
00117         LOG(llevError, "%s (%d)\n", ol->ob->name, ol->ob->count);
00118 }
00119 
00124 void clean_friendly_list(void) {
00125     objectlink *this, *prev = NULL, *next;
00126     int count = 0;
00127 
00128     for (this = first_friendly_object; this != NULL; this = next) {
00129         next = this->next;
00130         if (QUERY_FLAG(this->ob, FLAG_FREED)
00131         || !QUERY_FLAG(this->ob, FLAG_FRIENDLY)
00132         || (this->id != this->ob->count)) {
00133             if (prev) {
00134                 prev->next = this->next;
00135             } else {
00136                 first_friendly_object = this->next;
00137             }
00138             count++;
00139             free(this);
00140         /* If we removed the object, then prev is still valid.  */
00141         } else
00142             prev = this;
00143     }
00144     if (count)
00145         LOG(llevDebug, "clean_friendly_list: Removed %d bogus links\n", count);
00146 }
00147 
00157 int is_friendly(const object *op) {
00158     objectlink *ol;
00159 
00160     for (ol = first_friendly_object; ol != NULL; ol = ol->next)
00161         if (ol->ob == op)
00162             return 1;
00163 
00164     return 0;
00165 }