00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00030
00031
00032
00033
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;
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
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;
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--;
00188
00189 }
00190 if(Towed(mech)) {
00191
00192 int i;
00193 MECH *t;
00194
00195 for(i = 0; i < map->first_free; i++)
00196
00197 if((t = FindObjectsData(map->mechsOnMap[i])))
00198 if(MechCarrying(t) == mech->mynum) {
00199 SetCarrying(t, -1);
00200 MechStatus(mech) &= ~TOWED;
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
00245 if(MechAuto(mech) > 0) {
00246
00247 AUTO *a = FindObjectsData(MechAuto(mech));
00248
00249
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
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;
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 }