00001
00002 #include "revolt.h"
00003 #include "car.h"
00004 #include "ctrlread.h"
00005 #include "object.h"
00006 #include "player.h"
00007 #include "main.h"
00008 #include "editzone.h"
00009 #include "geom.h"
00010 #include "aizone.h"
00011 #include "ainode.h"
00012 #include "trigger.h"
00013 #ifdef _N64
00014 #include "ffs_code.h"
00015 #include "ffs_list.h"
00016 #include "utils.h"
00017 #endif
00018
00019
00020
00021 long AiZoneNum, AiZoneNumID;
00022 AIZONE *AiZones;
00023 AIZONE_HEADER *AiZoneHeaders;
00024
00026
00028 #ifdef _PC
00029 void LoadAiZones(char *file)
00030 {
00031 long i, j, k;
00032 FILE *fp;
00033 FILE_ZONE taz;
00034 AIZONE zone;
00035
00036
00037
00038 AiZones = NULL;
00039 AiZoneHeaders = NULL;
00040
00041
00042
00043 fp = fopen(file, "rb");
00044 if (!fp)
00045 {
00046 return;
00047 }
00048
00049
00050
00051 fread(&AiZoneNum, sizeof(AiZoneNum), 1, fp);
00052 if (!AiZoneNum)
00053 {
00054 fclose(fp);
00055 return;
00056 }
00057
00058
00059
00060 AiZones = (AIZONE*)malloc(sizeof(AIZONE) * AiZoneNum);
00061 if (!AiZones)
00062 {
00063 fclose(fp);
00064 Box(NULL, "Can't alloc memory for AI zones!", MB_OK);
00065 QuitGame = TRUE;
00066 return;
00067 }
00068
00069
00070
00071 for (i = 0 ; i < AiZoneNum ; i++)
00072 {
00073
00074
00075
00076 fread(&taz, sizeof(taz), 1, fp);
00077
00078
00079
00080 AiZones[i].ID = taz.ID;
00081
00082
00083
00084 AiZones[i].Size[0] = taz.Size[0];
00085 AiZones[i].Size[1] = taz.Size[1];
00086 AiZones[i].Size[2] = taz.Size[2];
00087
00088
00089
00090 AiZones[i].Pos = taz.Pos;
00091
00092
00093
00094 AiZones[i].Plane[0].v[A] = taz.Matrix.m[RX];
00095 AiZones[i].Plane[0].v[B] = taz.Matrix.m[RY];
00096 AiZones[i].Plane[0].v[C] = taz.Matrix.m[RZ];
00097 AiZones[i].Plane[0].v[D] = -DotProduct(&taz.Matrix.mv[R], &taz.Pos);
00098
00099 AiZones[i].Plane[1].v[A] = taz.Matrix.m[UX];
00100 AiZones[i].Plane[1].v[B] = taz.Matrix.m[UY];
00101 AiZones[i].Plane[1].v[C] = taz.Matrix.m[UZ];
00102 AiZones[i].Plane[1].v[D] = -DotProduct(&taz.Matrix.mv[U], &taz.Pos);
00103
00104 AiZones[i].Plane[2].v[A] = taz.Matrix.m[LX];
00105 AiZones[i].Plane[2].v[B] = taz.Matrix.m[LY];
00106 AiZones[i].Plane[2].v[C] = taz.Matrix.m[LZ];
00107 AiZones[i].Plane[2].v[D] = -DotProduct(&taz.Matrix.mv[L], &taz.Pos);
00108 }
00109
00110
00111
00112 for (i = AiZoneNum - 1 ; i ; i--) for (j = 0 ; j < i ; j++) if (AiZones[j].ID > AiZones[j + 1].ID)
00113 {
00114 zone = AiZones[j];
00115 AiZones[j] = AiZones[j + 1];
00116 AiZones[j + 1] = zone;
00117 }
00118
00119
00120
00121 AiZoneNumID = AiZones[AiZoneNum - 1].ID + 1;
00122
00123
00124
00125 AiZoneHeaders = (AIZONE_HEADER*)malloc(sizeof(AIZONE_HEADER) * AiZoneNumID);
00126 if (!AiZoneHeaders)
00127 {
00128 fclose(fp);
00129 Box(NULL, "Can't alloc memory for AI zone headers!", MB_OK);
00130 QuitGame = TRUE;
00131 return;
00132 }
00133
00134
00135
00136 for (i = 0 ; i < AiZoneNumID ; i++)
00137 {
00138 j = 0;
00139 while (AiZones[j].ID != i && j < AiZoneNum) j++;
00140 if (j == AiZoneNum)
00141 {
00142 AiZoneHeaders[i].Zones = AiZones;
00143 AiZoneHeaders[i].Count = 0;
00144 }
00145 else
00146 {
00147 AiZoneHeaders[i].Zones = &AiZones[j];
00148 k = 0;
00149 while (AiZones[j].ID == i && j < AiZoneNum) j++, k++;
00150 AiZoneHeaders[i].Count = k;
00151 }
00152 }
00153
00154
00155
00156 fclose(fp);
00157 }
00158 #endif
00159
00160
00161
00162
00163
00164 #ifdef _N64
00165 void LoadAiZones(void)
00166 {
00167 long i, j, k;
00168 FIL *fp;
00169 FILE_ZONE taz;
00170 AIZONE zone;
00171
00172
00173
00174 AiZones = NULL;
00175 AiZoneHeaders = NULL;
00176
00177
00178
00179 printf("Loading AI zones.\n");
00180 fp = FFS_Open(FFS_TYPE_TRACK | TRK_AIZONES);
00181 if (!fp)
00182 {
00183 printf("...<!> Failed to open AI zone file.\n");
00184 return;
00185 }
00186
00187
00188 FFS_Read(&AiZoneNum, sizeof(AiZoneNum), fp);
00189 if (!AiZoneNum)
00190 {
00191 printf("...<!> Number of AI Zones is zero, skipping.\n");
00192 FFS_Close(fp);
00193 return;
00194 }
00195 AiZoneNum = EndConvLong(AiZoneNum);
00196
00197
00198 AiZones = (AIZONE*)malloc(sizeof(AIZONE) * AiZoneNum);
00199 if (!AiZones)
00200 {
00201 ERROR("AIZ", "LoadAiZones", "Failed to alloc memory for AI zones", 1);
00202 }
00203
00204
00205 for (i = 0 ; i < AiZoneNum ; i++)
00206 {
00207
00208
00209 FFS_Read(&taz, sizeof(taz), fp);
00210 taz.ID = EndConvLong(taz.ID);
00211 taz.Pos.v[0] = EndConvReal(taz.Pos.v[0]);
00212 taz.Pos.v[1] = EndConvReal(taz.Pos.v[1]);
00213 taz.Pos.v[2] = EndConvReal(taz.Pos.v[2]);
00214 for (j = 0; j < 9; j++)
00215 {
00216 taz.Matrix.m[j] = EndConvReal(taz.Matrix.m[j]);
00217 }
00218 taz.Size[0] = EndConvReal(taz.Size[0]);
00219 taz.Size[1] = EndConvReal(taz.Size[1]);
00220 taz.Size[2] = EndConvReal(taz.Size[2]);
00221
00222
00223 AiZones[i].ID = taz.ID;
00224
00225
00226 AiZones[i].Size[0] = taz.Size[0];
00227 AiZones[i].Size[1] = taz.Size[1];
00228 AiZones[i].Size[2] = taz.Size[2];
00229
00230
00231 AiZones[i].Pos.v[X] = taz.Pos.v[X];
00232 AiZones[i].Pos.v[Y] = taz.Pos.v[Y];
00233 AiZones[i].Pos.v[Z] = taz.Pos.v[Z];
00234
00235
00236 AiZones[i].Plane[0].v[A] = taz.Matrix.m[RX];
00237 AiZones[i].Plane[0].v[B] = taz.Matrix.m[RY];
00238 AiZones[i].Plane[0].v[C] = taz.Matrix.m[RZ];
00239 AiZones[i].Plane[0].v[D] = -DotProduct(&taz.Matrix.mv[R], &taz.Pos);
00240
00241 AiZones[i].Plane[1].v[A] = taz.Matrix.m[UX];
00242 AiZones[i].Plane[1].v[B] = taz.Matrix.m[UY];
00243 AiZones[i].Plane[1].v[C] = taz.Matrix.m[UZ];
00244 AiZones[i].Plane[1].v[D] = -DotProduct(&taz.Matrix.mv[U], &taz.Pos);
00245
00246 AiZones[i].Plane[2].v[A] = taz.Matrix.m[LX];
00247 AiZones[i].Plane[2].v[B] = taz.Matrix.m[LY];
00248 AiZones[i].Plane[2].v[C] = taz.Matrix.m[LZ];
00249 AiZones[i].Plane[2].v[D] = -DotProduct(&taz.Matrix.mv[L], &taz.Pos);
00250 }
00251
00252
00253 for (i = AiZoneNum - 1 ; i ; i--) for (j = 0 ; j < i ; j++) if (AiZones[j].ID > AiZones[j + 1].ID)
00254 {
00255 zone = AiZones[j];
00256 AiZones[j] = AiZones[j + 1];
00257 AiZones[j + 1] = zone;
00258 }
00259
00260
00261 AiZoneNumID = AiZones[AiZoneNum - 1].ID + 1;
00262
00263
00264 AiZoneHeaders = (AIZONE_HEADER*)malloc(sizeof(AIZONE_HEADER) * AiZoneNumID);
00265 if (!AiZoneHeaders)
00266 {
00267 ERROR("AIZ", "LoadAiZones", "Unable to alloc memory for AI zone headers", 1);
00268 }
00269
00270
00271 for (i = 0 ; i < AiZoneNumID ; i++)
00272 {
00273 j = 0;
00274 while (AiZones[j].ID != i && j < AiZoneNum) j++;
00275 if (j == AiZoneNum)
00276 {
00277 AiZoneHeaders[i].Zones = AiZones;
00278 AiZoneHeaders[i].Count = 0;
00279 }
00280 else
00281 {
00282 AiZoneHeaders[i].Zones = &AiZones[j];
00283 k = 0;
00284 while (AiZones[j].ID == i && j < AiZoneNum) j++, k++;
00285 AiZoneHeaders[i].Count = k;
00286 }
00287 }
00288
00289
00290 FFS_Close(fp);
00291 }
00292 #endif
00293
00295
00297
00298 void FreeAiZones(void)
00299 {
00300 free(AiZones);
00301 free(AiZoneHeaders);
00302 }
00303
00305
00307
00308 char UpdateCarAiZone(PLAYER *Player)
00309 {
00310 long i, j, flag, nextzone;
00311 float dist;
00312 AIZONE *zone;
00313 CAR *car = &Player->car;
00314
00315
00316
00317 if (!AiZones)
00318 return FALSE;
00319
00320
00321
00322 nextzone = (Player->CarAI.ZoneID + 1) % AiZoneNumID;
00323 zone = AiZoneHeaders[nextzone].Zones;
00324
00325 for (i = 0 ; i < AiZoneHeaders[nextzone].Count ; i++, zone++)
00326 {
00327
00328
00329
00330 flag = FALSE;
00331 for (j = 0 ; j < 3 ; j++)
00332 {
00333 dist = PlaneDist(&zone->Plane[j], &car->Body->Centre.Pos);
00334 if (dist < -zone->Size[j] || dist > zone->Size[j])
00335 {
00336 flag = TRUE;
00337 break;
00338 }
00339 }
00340
00341
00342
00343 if (!flag)
00344 {
00345
00346
00347
00348 if (!(Player->CarAI.ZoneID = nextzone))
00349 {
00350 if (car == &PLR_LocalPlayer->car)
00351 ResetTriggerFlags(TRIGGER_TRACK_DIR);
00352
00353 return TRUE;
00354 }
00355
00356
00357
00358 return FALSE;
00359 }
00360 }
00361
00362
00363
00364 return FALSE;
00365 }
00366
00367