00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <Windows.h>
00016 #include <Assert.h>
00017 #include <Math.h>
00018
00019 #include "GMain.h"
00020 extern void GenVS_Error(const char *Msg, ...);
00021 typedef struct
00022 {
00023 geVec3d LookPos;
00024 uint32 MotionOnOff;
00025
00026 } Turret_Data;
00027
00028 typedef struct
00029 {
00030 int32 NumMotions;
00031 uint8 MotionIndex[3];
00032 } Motion_Table;
00033
00034 Motion_Table MotionTable[2] = {
00035 {1, ACTOR_MOTION_T1, MOTION_INDEX_NONE, MOTION_INDEX_NONE},
00036 {1, ACTOR_MOTION_T2, MOTION_INDEX_NONE, MOTION_INDEX_NONE},
00037 };
00038
00039 void ChangeTurretState(GPlayer *Player);
00040 void Vec3d_RotateY(geVec3d *Source, geVec3d *Origin, float RadAmount);
00041
00042
00043
00044 geBoolean Attacker_ControlTurret(GenVSI *VSI, void *PlayerData, float Time)
00045 {
00046 #define MY_PI (3.15159f)
00047 #define HALF_PI (MY_PI/2.0f)
00048 #define MY_PI2 (MY_PI*2)
00049
00050 GPlayer *Player, *Target;
00051 Turret_Data *TData;
00052 geVec3d Vect;
00053 float RAngle, Length, DeltaY;
00054 int32 i;
00055
00056 Player = (GPlayer*)PlayerData;
00057
00058 Target = GenVSI_GetNextPlayerInRadius(VSI, Player, NULL, "ClientPlayer", 400.0f);
00059
00060 TData = (Turret_Data*)Player->userData;
00061
00062 if (Target)
00063 {
00064 geVec3d TPos;
00065
00066 TPos = Target->XForm.Translation;
00067 TPos.Y += 140.0f;
00068
00069
00070 geVec3d_Subtract(&TPos, &TData->LookPos, &Vect);
00071 Length = geVec3d_Normalize(&Vect);
00072 geVec3d_AddScaled(&TData->LookPos, &Vect, Length*2.0f*Time, &TData->LookPos);
00073
00074 if (Player->Time >= 1.5f)
00075 {
00076 Attacker_Fire(VSI, Player, Target, Time);
00077 Player->Time = 0.0f;
00078 }
00079
00080 Player->Time += Time;
00081 }
00082 else
00083 {
00084 switch(Player->State)
00085 {
00086 case PSTATE_LookLeft:
00087 {
00088 Vec3d_RotateY(&TData->LookPos, &Player->XForm.Translation, 0.02f);
00089 break;
00090 }
00091 case PSTATE_LookRight:
00092 {
00093 Vec3d_RotateY(&TData->LookPos, &Player->XForm.Translation, -0.02f);
00094 break;
00095 }
00096 case PSTATE_LookUp:
00097 {
00098 if (TData->LookPos.Y < Player->XForm.Translation.Y+60.0f)
00099 TData->LookPos.Y += 200.0f*Time;
00100 else
00101 Player->State = PSTATE_LookLeft;
00102 break;
00103 }
00104 case PSTATE_LookDown:
00105 {
00106 if (TData->LookPos.Y > Player->XForm.Translation.Y-80.0f)
00107 TData->LookPos.Y -= 200.0f*Time;
00108 else
00109 Player->State = PSTATE_LookLeft;
00110 break;
00111 }
00112 case PSTATE_Normal:
00113 {
00114 break;
00115 }
00116 }
00117
00118 ChangeTurretState(Player);
00119 }
00120
00121
00122
00123
00124 geVec3d_Subtract(&Player->XForm.Translation, &TData->LookPos, &Vect);
00125 DeltaY = Vect.Y;
00126 Length = geVec3d_Normalize(&Vect);
00127
00128
00129 RAngle = (float)atan2(Vect.X, Vect.Z);
00130 geXForm3d_SetZRotation(&Player->XFormData[0].XForm, RAngle-MY_PI);
00131
00132
00133 RAngle = (float)acos(-DeltaY / Length);
00134
00135 geXForm3d_SetXRotation(&Player->XFormData[1].XForm, RAngle-HALF_PI);
00136
00137
00138 AnimatePlayer(VSI, PlayerData, Player->MotionIndex, Time, GE_TRUE);
00139
00140 for (i=0; i<2; i++)
00141 {
00142 uint32 Bit;
00143
00144 Bit = (1<<i);
00145
00146 if (!(Bit&TData->MotionOnOff))
00147 {
00148 if ((rand() % 100) > 98)
00149 TData->MotionOnOff |= Bit;
00150
00151 continue;
00152 }
00153
00154 if (AnimatePlayer2(VSI, PlayerData, i, Time, GE_TRUE))
00155 {
00156 if ((rand() % 100) > 40)
00157 TData->MotionOnOff &= ~Bit;
00158 }
00159 }
00160
00161 return GE_TRUE;
00162 }
00163
00164
00165
00166 geBoolean Attacker_TurretSpawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
00167 {
00168 AttackerTurret *Turret;
00169 GPlayer *Player;
00170 Turret_Data *TData;
00171
00172 Player = (GPlayer*)PlayerData;
00173
00174 Player->Time = 0.0f;
00175 Player->Control = Attacker_ControlTurret;
00176
00177 if (ClassData == NULL)
00178 {
00179 GenVS_Error("Attacker_TurrentSpawn: entity missing class data ('%s')\n",EntityName);
00180 }
00181
00182 Turret = (AttackerTurret*)ClassData;
00183
00184 geXForm3d_SetIdentity(&Player->XForm);
00185 geXForm3d_SetTranslation(&Player->XForm, Turret->Origin.X, Turret->Origin.Y, Turret->Origin.Z);
00186
00187 Player->VPos = Player->XForm.Translation;
00188
00189 geVec3d_Set(&Player->Mins, -50.0f, -50.0f, -50.0f);
00190 geVec3d_Set(&Player->Maxs, 50.0f, 50.0f, 50.0f);
00191
00192 Player->Scale = 0.4f;
00193 Player->State = PSTATE_LookLeft;
00194
00195
00196 Player->ViewFlags = VIEW_TYPE_ACTOR | VIEW_TYPE_HACK;
00197 Player->ViewIndex = ACTOR_INDEX_TURRET;
00198 Player->MotionIndex = ACTOR_MOTION_T1;
00199
00200
00201 Player->NumXFormData = 2;
00202
00203 Player->XFormData[0].XForm = Player->XForm;
00204 Player->XFormData[0].BoneIndex = 0;
00205
00206 Player->XFormData[1].XForm = Player->XForm;
00207 Player->XFormData[1].BoneIndex = 1;
00208
00209
00210 Player->NumMotionData = 2;
00211
00212 Player->MotionData[0].MotionTime = 0.0f;
00213 Player->MotionData[0].MotionIndex = ACTOR_MOTION_T1;
00214
00215 Player->MotionData[1].MotionTime = 0.0f;
00216 Player->MotionData[1].MotionIndex = ACTOR_MOTION_T2;
00217
00218 TData = GE_RAM_ALLOCATE_STRUCT(Turret_Data);
00219
00220 if (!TData)
00221 return GE_FALSE;
00222
00223 memset(TData, 0, sizeof(Turret_Data));
00224
00225 TData->LookPos = Player->XForm.Translation;
00226 TData->LookPos.Z += 40.0f;
00227
00228 Player->userData = TData;
00229
00230 return GE_TRUE;
00231 }
00232
00233
00234
00235 void Attacker_TurretDestroy(GenVSI *VSI, void *PlayerData, void *ClassData)
00236 {
00237 GPlayer *Player;
00238
00239 Player = (GPlayer*)PlayerData;
00240
00241 if (Player->userData)
00242 geRam_Free(Player->userData);
00243
00244 }
00245
00246
00247
00248
00249 void Attacker_Fire(GenVSI *VSI, GPlayer *Player, GPlayer *Target, float Time)
00250 {
00251 GPlayer *Weapon;
00252
00253 Weapon = GenVSI_SpawnPlayer(VSI, "Attacker_Fire");
00254
00255 if (!Weapon)
00256 {
00257 return;
00258 }
00259
00260
00261 Weapon->Control = Blaster_Control;
00262 Weapon->Blocked = NULL;
00263 Weapon->Trigger = NULL;
00264 Weapon->Owner = Player;
00265 Weapon->Time = 0.0f;
00266 Weapon->PingTime = Player->PingTime;
00267
00268 Weapon->ControlIndex = 5;
00269
00270 Weapon->ViewFlags = (VIEW_TYPE_SPRITE | VIEW_TYPE_LIGHT);
00271 Weapon->ViewIndex = TEXTURE_INDEX_WEAPON2;
00272 Weapon->Scale = 1.0f;
00273 Weapon->FxFlags = FX_PARTICLE_TRAIL;
00274
00275 XFormFromVector(&Player->XForm.Translation, &Target->XForm.Translation, 0.0f, &Weapon->XForm);
00276
00277
00278 GenVSI_PlaySound(VSI, SOUND_INDEX_BLASTER, &Player->XForm.Translation);
00279
00280 Weapon->VPos = Player->XForm.Translation;
00281 }
00282
00283 void ChangeTurretState(GPlayer *Player)
00284 {
00285 int32 Seed;
00286
00287 Seed = rand() % 100;
00288
00289 if (Seed > 97)
00290 Player->State = PSTATE_LookRight;
00291 else if (Seed > 96)
00292 Player->State = PSTATE_LookUp;
00293 else if (Seed > 94)
00294 Player->State = PSTATE_LookDown;
00295 else if (Seed > 90)
00296 Player->State = PSTATE_Normal;
00297 }
00298
00299 void Vec3d_RotateY(geVec3d *Source, geVec3d *Origin, float RadAmount)
00300 {
00301 geXForm3d XForm;
00302
00303 geVec3d_Subtract(Source, Origin, Source);
00304
00305 geXForm3d_SetYRotation(&XForm, RadAmount);
00306 geXForm3d_Transform(&XForm, Source, Source);
00307
00308 geVec3d_Add(Source, Origin, Source);
00309 }