src/hcode/btech/map.dynamic.c

Go to the documentation of this file.
00001 
00002 /*
00003  * $Id: map.dynamic.c,v 1.1.1.1 2005/01/11 21:18:08 kstevens Exp $
00004  *
00005  * Author: Markus Stenberg <fingon@iki.fi>
00006  *
00007  *  Copyright (c) 1996 Markus Stenberg
00008  *  Copyright (c) 1998-2002 Thomas Wouters
00009  *  Copyright (c) 2000-2002 Cord Awtry
00010  *       All rights reserved
00011  *
00012  * Created: Sun Oct 13 19:38:31 1996 fingon
00013  * Last modified: Sun Jun 14 14:54:11 1998 fingon
00014  *
00015  */
00016 
00017 #include <stdio.h>
00018 
00019 #include "create.h"
00020 #include "mech.h"
00021 #include "autopilot.h"
00022 #include "p.econ_cmds.h"
00023 #include "p.mech.restrict.h"
00024 #include "p.mech.utils.h"
00025 #include "p.map.conditions.h"
00026 
00027 #define DYNAMIC_MAGIC 42
00028 
00029 /* Code for saving / loading / setting / unsetting the dynamic pieces
00030    of map structure:
00031    - mechsOnMap
00032    - LOSinfo
00033    - mechflags
00034    */
00035 
00036 #define CHELO(a,b,c,d) if (!(ugly_kludge++)) { \
00037     if ((tmp=fread(a,b,c,d)) != c) { fprintf (stderr, "Error loading mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); return; } } else { if ((tmp=fread(a,b,c,d)) != c) { fprintf (stderr, "Error loading mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); } }
00038 #define CHESA(a,b,c,d) if ((tmp=fwrite(a,b,c,d)) != c) { fprintf (stderr, "Error writing mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); }
00039 
00040 static int ugly_kludge = 0;             /* Nonfatal for _first_ */
00041 
00042 void load_mapdynamic(FILE * f, MAP * map)
00043 {
00044         int count = map->first_free;
00045         int i, tmp;
00046         unsigned char tmpb;
00047 
00048         if(count > 0) {
00049                 Create(map->mechsOnMap, dbref, count);
00050 
00051                 CHELO(map->mechsOnMap, sizeof(map->mechsOnMap[0]), count, f);
00052                 Create(map->mechflags, char, count);
00053 
00054                 CHELO(map->mechflags, sizeof(map->mechflags[0]), count, f);
00055                 Create(map->LOSinfo, unsigned short *, count);
00056 
00057                 for(i = 0; i < count; i++) {
00058                         Create(map->LOSinfo[i], unsigned short, count);
00059 
00060                         CHELO(map->LOSinfo[i], sizeof(map->LOSinfo[i][0]), count, f);
00061                 }
00062         } else {
00063                 map->mechsOnMap = NULL;
00064                 map->mechflags = NULL;
00065                 map->LOSinfo = NULL;
00066         }
00067         CHELO(&tmpb, 1, 1, f);
00068         if(tmpb != DYNAMIC_MAGIC) {
00069                 fprintf(stderr, "Error reading data for obj #%d (%d != %d)!\n",
00070                                 map->mynum, tmpb, DYNAMIC_MAGIC);
00071                 fflush(stderr);
00072                 exit(1);
00073         }
00074 }
00075 
00076 #define outbyte(a) tmpb=(a);CHESA(&tmpb, 1, 1, f);
00077 
00078 void save_mapdynamic(FILE * f, MAP * map)
00079 {
00080         int count = map->first_free;
00081         int i, tmp;
00082         unsigned char tmpb;
00083 
00084         if(count > 0) {
00085                 CHESA(map->mechsOnMap, sizeof(map->mechsOnMap[0]), count, f);
00086                 CHESA(map->mechflags, sizeof(map->mechflags[0]), count, f);
00087                 for(i = 0; i < count; i++)
00088                         CHESA(map->LOSinfo[i], sizeof(map->LOSinfo[i][0]), count, f);
00089         }
00090         outbyte(DYNAMIC_MAGIC);
00091 }
00092 
00093 void mech_map_consistency_check(MECH * mech)
00094 {
00095         MAP *map = getMap(mech->mapindex);
00096 
00097         if(!map) {
00098                 if(mech->mapindex > 0) {
00099                         mech->mapindex = -1;
00100                         fprintf(stderr, "#%d on nonexistent map - removing..\n",
00101                                         mech->mynum);
00102                 }
00103                 return;
00104         }
00105         if(map->first_free <= mech->mapnumber) {
00106                 /* Invalid: possible corruption of data, therefore un-hosing it */
00107                 mech->mapindex = -1;
00108                 mech_remove_from_all_maps(mech);
00109                 fprintf(stderr, "#%d on invalid map - removing.. (#1)\n",
00110                                 mech->mynum);
00111                 return;
00112         }
00113         if(map->mechsOnMap[mech->mapnumber] != mech->mynum) {
00114                 fprintf(stderr, "#%d on invalid map - removing .. (#2) -- mapindex: %d mapnumber: %d mechsOnMap: %d\n",
00115                                 mech->mynum, mech->mapindex, mech->mapnumber, map->mechsOnMap[mech->mapnumber]);
00116                 mech->mapindex = -1;
00117                 mech_remove_from_all_maps(mech);
00118                 return;
00119         }
00120         mech_remove_from_all_maps_except(mech, map->mynum);
00121 }
00122 
00123 void eliminate_empties(MAP * map)
00124 {
00125         int i;
00126         int j;
00127         int count, oldcount;
00128         char tempbuf[SBUF_SIZE];
00129 
00130         if(!map)
00131                 return;
00132         for(i = map->first_free - 1; i >= 0; i--)
00133                 if(map->mechsOnMap[i] > 0)
00134                         break;
00135         count = i + 1;
00136         if(count == (oldcount = map->first_free))
00137                 return;
00138         fprintf(stderr,
00139                         "Map #%d contains empty entries ; removing %d (%d->%d)\n",
00140                         map->mynum, oldcount - count, oldcount, count);
00141         if(i < 0)
00142                 return;
00143         for(j = count; j < oldcount; j++)
00144                 free((void *) map->LOSinfo[j]);
00145         ReCreate(map->LOSinfo, unsigned short *, count);
00146 
00147         ReCreate(map->mechsOnMap, dbref, count);
00148         ReCreate(map->mechflags, char, count);
00149 
00150         map->first_free = count;
00151         sprintf(tempbuf, "%d", map->mynum);
00152         mech_Rfixstuff(GOD, NULL, tempbuf);
00153 }
00154 
00155 void remove_mech_from_map(MAP * map, MECH * mech)
00156 {
00157         int loop = map->first_free;
00158 
00159         clear_mech_from_LOS(mech);
00160         mech->mapindex = -1;
00161         if(map->first_free <= mech->mapnumber ||
00162            map->mechsOnMap[mech->mapnumber] != mech->mynum) {
00163                 SendError(tprintf
00164                                   ("Map indexing error for mech #%d: Map index %d contains data for #%d instead.",
00165                                    mech->mynum, mech->mapnumber,
00166                                    map->mechsOnMap ? map->mechsOnMap[mech->mapnumber] : -1));
00167                 if(map->mechsOnMap)
00168                         for(loop = 0;
00169                                 (loop < map->first_free) &&
00170                                 (map->mechsOnMap[loop] != mech->mynum); loop++);
00171         } else
00172                 loop = mech->mapnumber;
00173         mech->mapnumber = 0;
00174         if(loop != (map->first_free)) {
00175                 map->mechsOnMap[loop] = -1;     /* clear it */
00176                 map->mechflags[loop] = 0;
00177 #if 0
00178                 for(i = 0; i < map->first_free; i++)
00179                         if(map->mechsOnMap[i] > 0 && i != loop)
00180                                 if((t = getMech(map->mechsOnMap[i])))
00181                                         if(MechTeam(t) != MechTeam(mech) &&
00182                                            (map->LOSinfo[i][loop] & MECHLOSFLAG_SEEN)) {
00183                                                 MechNumSeen(t) = MAX(0, MechNumSeen(t) - 1);
00184                                         }
00185 #endif
00186                 if(loop == (map->first_free - 1))
00187                         map->first_free--;      /* Who cares about some lost memory? In realloc
00188                                                                    we'll gain it back anyway */
00189         }
00190         if(Towed(mech)) {
00191                 /* Check that the towing guy isn't left on the map */
00192                 int i;
00193                 MECH *t;
00194 
00195                 for(i = 0; i < map->first_free; i++)
00196                         /* Release from towing if tow-guy ain't on same map already */
00197                         if((t = FindObjectsData(map->mechsOnMap[i])))
00198                                 if(MechCarrying(t) == mech->mynum) {
00199                                         SetCarrying(t, -1);
00200                                         MechStatus(mech) &= ~TOWED;     /* Reset the Towed flag */
00201                                         break;
00202                                 }
00203         }
00204         MechNumSeen(mech) = 0;
00205         if(IsDS(mech))
00206                 SendDSInfo(tprintf("DS #%d has left map #%d", mech->mynum,
00207                                                    map->mynum));
00208 
00209 }
00210 
00211 void add_mech_to_map(MAP * newmap, MECH * mech)
00212 {
00213         int loop, count, i;
00214 
00215         for(loop = 0; loop < newmap->first_free; loop++)
00216                 if(newmap->mechsOnMap[loop] == mech->mynum)
00217                         break;
00218         if(loop != newmap->first_free)
00219                 return;
00220         for(loop = 0; loop < newmap->first_free; loop++)
00221                 if(newmap->mechsOnMap[loop] < 0)
00222                         break;
00223         if(loop == newmap->first_free) {
00224                 newmap->first_free++;
00225                 count = newmap->first_free;
00226                 ReCreate(newmap->mechsOnMap, dbref, count);
00227                 ReCreate(newmap->mechflags, char, count);
00228                 ReCreate(newmap->LOSinfo, unsigned short *, count);
00229 
00230                 newmap->LOSinfo[count - 1] = NULL;
00231                 for(i = 0; i < count; i++) {
00232                         ReCreate(newmap->LOSinfo[i], unsigned short, count);
00233 
00234                         newmap->LOSinfo[i][loop] = 0;
00235                 }
00236                 for(i = 0; i < count; i++)
00237                         newmap->LOSinfo[loop][i] = 0;
00238         }
00239         mech->mapindex = newmap->mynum;
00240         mech->mapnumber = loop;
00241         newmap->mechsOnMap[loop] = mech->mynum;
00242         newmap->mechflags[loop] = 0;
00243 
00244         /* Is there an autopilot */
00245         if(MechAuto(mech) > 0) {
00246 
00247                 AUTO *a = FindObjectsData(MechAuto(mech));
00248 
00249                 /* Reset the AI's comtitle */
00250                 if(a)
00251                         auto_set_comtitle(a, mech);
00252         }
00253 
00254         if(Towed(mech)) {
00255                 int i;
00256                 MECH *t;
00257 
00258                 for(i = 0; i < newmap->first_free; i++)
00259                         /* Release from towing if tow-guy ain't on same map already */
00260                         if((t = FindObjectsData(newmap->mechsOnMap[i])))
00261                                 if(MechCarrying(t) == mech->mynum)
00262                                         break;
00263                 if(i == newmap->first_free)
00264                         MechStatus(mech) &= ~TOWED;     /* Reset the Towed flag */
00265         }
00266         MarkForLOSUpdate(mech);
00267         UnZombifyMech(mech);
00268         UpdateConditions(mech, newmap);
00269         if(IsDS(mech))
00270                 SendDSInfo(tprintf("DS #%d has entered map #%d", mech->mynum,
00271                                                    newmap->mynum));
00272 }
00273 
00274 int mech_size(MAP * map)
00275 {
00276         return map->first_free * (sizeof(dbref) + sizeof(char) +
00277                                                           sizeof(unsigned short *) +
00278                                                           map->first_free * sizeof(unsigned short));
00279 }

Generated on Mon May 28 04:25:21 2007 for BattletechMUX by  doxygen 1.4.7