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