Crossfire Server, Branch 1.12
R12190
|
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 }