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
00021 #include "Quatern.h"
00022
00023 #define INCHES_PER_METER (39.37007874016f)
00024
00025 void GenVS_Error(const char *Msg, ...);
00026
00027
00028
00029
00030
00031
00032 geBoolean Client_Control(GenVSI *VSI, void *PlayerData, float Time);
00033 static geBoolean Door_Control(GenVSI *VSI, void *PlayerData, float Time);
00034 static geBoolean Plat_Control(GenVSI *VSI, void *PlayerData, float Time);
00035 static geBoolean Door_Trigger(GenVSI *VSI, void *PlayerData, void *TargetData, void* data);
00036 void SetupPlayerXForm(GenVSI *VSI, void *PlayerData, float Time);
00037
00038 geBoolean Bot_Main(GenVSI *VSI, const char *LevelName);
00039 static geBoolean Player_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData,char *EntityName);
00040 static geBoolean Door_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData,char *EntityName);
00041 static geBoolean Plat_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData,char *EntityName);
00042 static geBoolean Plat_Trigger(GenVSI *VSI, void *PlayerData, void *TargetData, void* data);
00043
00044
00045 static geBoolean PhysicsObject_Spawn(GenVSI* VSI, void* PlayerData, void* Class,char *EntityName);
00046 static void PhysicsObject_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData);
00047 static geBoolean PhysicsObject_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data);
00048 static geBoolean PhysicsObject_Control(GenVSI* VSI, void* PlayerData, float Time);
00049
00050 static geBoolean PhysicsJoint_Spawn(GenVSI* VSI, void* PlayerData, void* Class,char *EntityName);
00051 static void PhysicsJoint_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData);
00052 static geBoolean PhysicsJoint_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data);
00053 static geBoolean PhysicsJoint_Control(GenVSI* VSI, void* PlayerData, float Time);
00054
00055 static geBoolean PhysicalSystem_Spawn(GenVSI* VSI, void* PlayerData, void* Class,char *EntityName);
00056 static void PhysicalSystem_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData);
00057 static geBoolean PhysicalSystem_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data);
00058 static geBoolean PhysicalSystem_Control(GenVSI* VSI, void* PlayerData, float Time);
00059
00060 static geBoolean ForceField_Spawn(GenVSI* VSI, void* PlayerData, void* Class,char *EntityName);
00061 static geBoolean ForceField_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data);
00062 static geBoolean ForceField_Control(GenVSI* VSI, void* PlayerData, float Time);
00063
00064 static geBoolean IsKeyDown(int KeyCode);
00065
00066 GPlayer *CurrentPlayerStart;
00067
00068
00069
00070
00071
00072
00073 geBoolean Server_Main(GenVSI *VSI, const char *LevelName)
00074 {
00075 Bot_Main(VSI, LevelName);
00076
00077 CurrentPlayerStart = NULL;
00078
00079
00080
00081 GenVSI_SetClassSpawn(VSI, "DeathMatchStart", Player_Spawn, NULL);
00082
00083
00084 GenVSI_SetClassSpawn(VSI, "Door", Door_Spawn, NULL);
00085 GenVSI_SetClassSpawn(VSI, "MovingPlat", Plat_Spawn, NULL);
00086
00087 GenVSI_SetClassSpawn(VSI, "PhysicsObject", PhysicsObject_Spawn, PhysicsObject_Destroy);
00088 GenVSI_SetClassSpawn(VSI, "PhysicsJoint", PhysicsJoint_Spawn, PhysicsJoint_Destroy);
00089 GenVSI_SetClassSpawn(VSI, "PhysicalSystem", PhysicalSystem_Spawn, PhysicalSystem_Destroy);
00090 GenVSI_SetClassSpawn(VSI, "ForceField", ForceField_Spawn, NULL);
00091
00092
00093
00094 GenVSI_SetClassSpawn(VSI, "ChangeLevel", ChangeLevel_Spawn, NULL);
00095
00096
00097 GenVSI_SetClassSpawn(VSI, "ItemHealth", Item_HealthSpawn, NULL);
00098 GenVSI_SetClassSpawn(VSI, "ItemArmor", Item_ArmorSpawn, NULL);
00099 GenVSI_SetClassSpawn(VSI, "ItemRocket", Item_RocketSpawn, NULL);
00100 GenVSI_SetClassSpawn(VSI, "ItemRocketAmmo", Item_RocketAmmoSpawn, NULL);
00101 GenVSI_SetClassSpawn(VSI, "ItemGrenade", Item_GrenadeSpawn, NULL);
00102 GenVSI_SetClassSpawn(VSI, "ItemGrenadeAmmo", Item_GrenadeAmmoSpawn, NULL);
00103 GenVSI_SetClassSpawn(VSI, "ItemShredder", Item_ShredderSpawn, NULL);
00104 GenVSI_SetClassSpawn(VSI, "ItemShredderAmmo", Item_ShredderAmmoSpawn, NULL);
00105
00106 GenVSI_SetClassSpawn(VSI, "AttackerTurret", Attacker_TurretSpawn, Attacker_TurretDestroy);
00107
00108
00109
00110 GenVSI_SetWorld(VSI, SetupWorldCB, ShutdownWorldCB, LevelName);
00111
00112
00113 GenVSI_ProcIndex(VSI, 0, Client_Control);
00114 GenVSI_ProcIndex(VSI, 1, Door_Control);
00115 GenVSI_ProcIndex(VSI, 2, Door_Trigger);
00116 GenVSI_ProcIndex(VSI, 3, Plat_Control);
00117 GenVSI_ProcIndex(VSI, 4, Plat_Trigger);
00118 GenVSI_ProcIndex(VSI, 5, Blaster_Control);
00119 GenVSI_ProcIndex(VSI, 6, Rocket_Control);
00120 GenVSI_ProcIndex(VSI, 7, Grenade_Control);
00121 GenVSI_ProcIndex(VSI, 8, Shredder_Control);
00122 GenVSI_ProcIndex(VSI, 9, Item_ControlHealth);
00123
00124 return GE_TRUE;
00125 }
00126
00127
00128
00129
00130 geBoolean Client_Main(GenVSI *VSI)
00131 {
00132 GenVSI_ProcIndex(VSI, 0, Client_Control);
00133 GenVSI_ProcIndex(VSI, 1, Door_Control);
00134 GenVSI_ProcIndex(VSI, 2, Door_Trigger);
00135 GenVSI_ProcIndex(VSI, 3, Plat_Control);
00136 GenVSI_ProcIndex(VSI, 4, Plat_Trigger);
00137 GenVSI_ProcIndex(VSI, 5, Blaster_Control);
00138 GenVSI_ProcIndex(VSI, 6, Rocket_Control);
00139 GenVSI_ProcIndex(VSI, 7, Grenade_Control);
00140 GenVSI_ProcIndex(VSI, 8, Shredder_Control);
00141 GenVSI_ProcIndex(VSI, 9, Item_ControlHealth);
00142
00143 return GE_TRUE;
00144 }
00145
00146
00147 geBoolean SelfCollisionCB(geWorld_Model *Model, geActor *Actor, void *Context)
00148 {
00149 if (Actor)
00150 {
00151 CData *Data;
00152
00153 Data = (CData*)Context;
00154
00155 assert(Data);
00156 assert(Data->Player);
00157
00158 if (GenVSI_ActorToPlayer(Data->VSI, Actor) == Data->Player)
00159 return GE_FALSE;
00160
00161
00162 if (GenVSI_ActorToPlayer(Data->VSI, Actor) == Data->Player->Owner)
00163 return GE_FALSE;
00164 }
00165
00166 return GE_TRUE;
00167 }
00168
00169
00170 geBoolean SelfCollisionCB2(geWorld_Model *Model, geActor *Actor, void *Context)
00171 {
00172 if (Actor)
00173 {
00174 CData *Data;
00175
00176 Data = (CData*)Context;
00177
00178 assert(Data);
00179 assert(Data->Player);
00180
00181 if (GenVSI_ActorToPlayer(Data->VSI, Actor) == Data->Player)
00182 return GE_FALSE;
00183 }
00184
00185 return GE_TRUE;
00186 }
00187
00188 int32 GMode;
00189 extern int32 MenuBotCount;
00190
00191
00192
00193
00194 GPlayer *GetDMSpawn(GenVSI *VSI)
00195 {
00196
00197 if (GMode == 0 && !MenuBotCount)
00198 {
00199 CurrentPlayerStart = (GPlayer*)GenVSI_GetNextPlayer(VSI, CurrentPlayerStart, "PlayerStart");
00200
00201 if (!CurrentPlayerStart)
00202 CurrentPlayerStart = (GPlayer*)GenVSI_GetNextPlayer(VSI, NULL, "PlayerStart");
00203
00204
00205
00206
00207 if (!CurrentPlayerStart)
00208 CurrentPlayerStart = (GPlayer*)GenVSI_GetNextPlayer(VSI, NULL, "DeathMatchStart");
00209
00210 if (!CurrentPlayerStart)
00211 GenVS_Error( "Game_SpawnClient: No PlayerStart or DeathMatchStart!\n");
00212 }
00213 else
00214 {
00215 CurrentPlayerStart = (GPlayer*)GenVSI_GetNextPlayer(VSI, CurrentPlayerStart, "DeathMatchStart");
00216
00217 if (!CurrentPlayerStart)
00218 CurrentPlayerStart = (GPlayer*)GenVSI_GetNextPlayer(VSI, NULL, "DeathMatchStart");
00219
00220 if (!CurrentPlayerStart)
00221 GenVS_Error( "Game_SpawnClient: No DeathMatchStart!\n");
00222 }
00223
00224 return CurrentPlayerStart;
00225 }
00226
00227
00228
00229
00230 geBoolean Game_SpawnClient(GenVSI *VSI, geWorld *World, void *PlayerData, void *ClassData)
00231 {
00232 int32 i;
00233 GPlayer *Player;
00234
00235
00236 Player = (GPlayer*)PlayerData;
00237
00238 geXForm3d_SetIdentity(&Player->XForm);
00239
00240
00241 #ifndef FLY_MODE
00242 {
00243 GPlayer *DMStart;
00244
00245 DMStart = GetDMSpawn(VSI);
00246 Player->XForm = DMStart->XForm;
00247 }
00248
00249
00250 Player->Mins.X = -30.0f;
00251 Player->Mins.Y = -10.0f;
00252 Player->Mins.Z = -30.0f;
00253 Player->Maxs.X = 30.0f;
00254 Player->Maxs.Y = 160.0f;
00255 Player->Maxs.Z = 30.0f;
00256 #else
00257 Player->Mins.X =-5.0f;
00258 Player->Mins.Y =-5.0f;
00259 Player->Mins.Z =-5.0f;
00260 Player->Maxs.X = 5.0f;
00261 Player->Maxs.Y = 5.0f;
00262 Player->Maxs.Z = 5.0f;
00263 #endif
00264
00265 Player->Time = 0.0f;
00266 Player->JustSpawned = GE_TRUE;
00267
00268
00269 Player->GunOffset.X = 0.0f;
00270 Player->GunOffset.Y = 130.0f;
00271 Player->GunOffset.Z = 0.0f;
00272
00273 Player->Scale = 2.7f;
00274
00275
00276 Player->ViewFlags = VIEW_TYPE_ACTOR | VIEW_TYPE_YAW_ONLY | VIEW_TYPE_COLLIDEMODEL;
00277 Player->ViewIndex = ACTOR_INDEX_PLAYER;
00278 Player->MotionIndex = ACTOR_MOTION_PLAYER_RUN;
00279 Player->DammageFlags = DAMMAGE_TYPE_NORMAL | DAMMAGE_TYPE_RADIUS;
00280
00281
00282 Player->ControlIndex = 0;
00283 Player->Control = Client_Control;
00284
00285
00286 GenVSI_SetViewPlayer(VSI, Player->ClientHandle, Player);
00287
00288
00289
00290
00291
00292 Player->Health = 100;
00293 Player->Score = 0;
00294
00295
00296
00297
00298 GenVSI_SetClientScore(VSI, Player->ClientHandle, Player->Score);
00299 GenVSI_SetClientHealth(VSI, Player->ClientHandle, Player->Health);
00300
00301 for (i=0; i< MAX_PLAYER_ITEMS; i++)
00302 {
00303 Player->Inventory[i] = 0;
00304 Player->InventoryHas[i] = GE_FALSE;
00305 }
00306
00307 Player->CurrentWeapon = 0;
00308
00309 GenVSI_SetClientInventory(VSI, Player->ClientHandle, ITEM_GRENADES, 0, GE_FALSE);
00310 GenVSI_SetClientInventory(VSI, Player->ClientHandle, ITEM_ROCKETS, 0, GE_FALSE);
00311 GenVSI_SetClientInventory(VSI, Player->ClientHandle, ITEM_SHREDDER, 0, GE_FALSE);
00312
00313 Player->NextWeaponTime = 0.0f;
00314
00315 return GE_TRUE;
00316 }
00317
00318
00319
00320
00321 void Game_DestroyClient(GenVSI *VSI, void *PlayerData, void *ClassData)
00322 {
00323
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 int32 PlayerLiquid(GPlayer *Player)
00339 {
00340 if (Player->State == PSTATE_InLava)
00341 return 10;
00342 else if (Player->State == PSTATE_InWater)
00343 return 5;
00344
00345 return 0;
00346 }
00347
00348
00349
00350
00351 static geBoolean CheckPlayer(GenVSI *VSI, void *PlayerData)
00352 {
00353 geVec3d Mins, Maxs, Pos;
00354 GE_Contents Contents;
00355 GPlayer *Player;
00356 uint32 ColFlags;
00357
00358 Player = (GPlayer*)PlayerData;
00359
00360 Mins = Player->Mins;
00361 Maxs = Player->Maxs;
00362
00363 Pos = Player->XForm.Translation;
00364
00365 ColFlags = GE_COLLIDE_MODELS;
00366
00367 if (geWorld_GetContents(GenVSI_GetWorld(VSI), &Pos, &Mins, &Maxs, ColFlags, 0, NULL, NULL, &Contents))
00368 {
00369 if (Contents.Contents & GE_CONTENTS_SOLID)
00370 {
00371
00372 if (Player->JustSpawned)
00373 {
00374 GenVS_Error("Player_CheckPlayer: the player's starting position is bad - some of the player's bounding box is in solid space.");
00375 }
00376 Player->XForm.Translation = Player->LastGoodPos;
00377 Player->JustSpawned = 0;
00378 return GE_TRUE;
00379 }
00380 }
00381
00382 Player->JustSpawned = 0;
00383 return GE_FALSE;
00384 }
00385
00386 #define STEP_HEIGHT 42.0f
00387
00388
00389
00390
00391 geBoolean MovePlayerUpStep(GenVSI *VSI, void *PlayerData, GE_Collision *Collision)
00392 {
00393 geVec3d Mins, Maxs, Pos1, Pos2;
00394 GE_Collision Collision2;
00395 GPlayer *Player;
00396 geWorld *World;
00397
00398 Player = (GPlayer*)PlayerData;
00399
00400 World = GenVSI_GetWorld(VSI);
00401
00402 assert(World);
00403
00404 Mins = Player->Mins;
00405 Maxs = Player->Maxs;
00406
00407 Pos1 = Player->XForm.Translation;
00408 Pos2 = Player->XForm.Translation;
00409
00410 Pos2.Y += STEP_HEIGHT;
00411
00412
00413 if (geWorld_Collision(World, &Mins, &Maxs, &Pos1, &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS, 0, NULL, NULL, &Collision2))
00414 return GE_FALSE;
00415
00416
00417 Pos1 = Pos2;
00418 geVec3d_AddScaled(&Pos2, &Collision->Plane.Normal, -0.5f, &Pos2);
00419
00420 if (geWorld_Collision(World, &Mins, &Maxs, &Pos1, &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS, 0, NULL, NULL, &Collision2))
00421 return GE_FALSE;
00422
00423
00424 Pos1 = Pos2;
00425 Pos2.Y -= (STEP_HEIGHT+1.0f);
00426
00427
00428 if (geWorld_Collision(World, &Mins, &Maxs, &Pos1, &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS, 0, NULL, NULL, &Collision2))
00429 {
00430 Pos2 = Collision2.Impact;
00431 Player->State = PSTATE_Normal;
00432 }
00433 else
00434 return GE_FALSE;
00435
00436 Player->XForm.Translation = Pos2;
00437
00438 return GE_TRUE;
00439 }
00440
00441 #define MAX_CLIP_PLANES 5
00442
00443
00444
00445
00446 geBoolean CheckVelocity(GenVSI *VSI, void *PlayerData, float BounceScale, geBoolean AllowBounce, float Time)
00447 {
00448 int32 NumHits, NumPlanes;
00449 GE_Collision Collision;
00450 int32 HitCount, i, j;
00451 geVec3d Mins, Maxs;
00452 geVec3d Planes[MAX_CLIP_PLANES];
00453 geVec3d Pos, NewPos, OriginalVelocity, PrimalVelocity;
00454 geVec3d NewVelocity, Dir;
00455 float TimeLeft, Dist;
00456 GE_Contents Contents;
00457 GPlayer *Player;
00458 geWorld *World;
00459 uint32 ColFlags;
00460
00461 #if 0
00462 geEntity_EntitySet * Set;
00463 geEntity * Entity;
00464 geVec3d boundingBoxCenter,
00465 boundingBoxScale,
00466 forceFieldCenterToBBCenter;
00467 #endif
00468
00469
00471
00472
00473 Player = (GPlayer*)PlayerData;
00474
00475 World = GenVSI_GetWorld(VSI);
00476
00477 assert(World);
00478
00479 Mins = Player->Mins;
00480 Maxs = Player->Maxs;
00481
00482 geVec3d_Copy(&Player->Velocity, &OriginalVelocity);
00483 geVec3d_Copy(&Player->Velocity, &PrimalVelocity);
00484
00485 TimeLeft = Time;
00486
00487 NumHits = 4;
00488 NumPlanes = 0;
00489
00490 if (Player->State == PSTATE_Normal)
00491 Player->State = PSTATE_InAir;
00492
00493 ColFlags = GE_COLLIDE_MODELS;
00494
00496
00497 #if 0
00498 geVec3d_Copy(&Player->XForm.Translation, &boundingBoxCenter);
00499
00500 boundingBoxScale.X = (float)fabs(0.5f * (Maxs.X - Mins.X));
00501 boundingBoxScale.Y = (float)fabs(0.5f * (Maxs.Y - Mins.Y));
00502 boundingBoxScale.Z = (float)fabs(0.5f * (Maxs.Z - Mins.Z));
00503
00504 #pragma message ("Use: GenVSI_GetNextPlayer here...")
00505 Set = NULL;
00506 Set = geWorld_GetEntitySet(World, "ForceField");
00507 if (Set != NULL)
00508 {
00509 for (Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
00510 Entity != NULL;
00511 Entity = geEntity_EntitySetGetNextEntity(Set, Entity))
00512 {
00513 ForceField* ff;
00514 float forceMultiplier;
00515 float distToFFCenter;
00516 float forceMagnitude;
00517 geVec3d forceDir;
00518 geVec3d forceToApply;
00519 geVec3d impulse;
00520
00521 ff = geEntity_GetUserData(Entity);
00522 assert(ff != NULL);
00523
00524 if (! ff->affectsPlayers)
00525 continue;
00526
00527 geVec3d_Subtract(&boundingBoxCenter, &ff->Origin, &forceFieldCenterToBBCenter);
00528 geVec3d_Copy(&forceFieldCenterToBBCenter, &forceDir);
00529 #pragma message("does geVec3d_Normalize() return length?")
00530 geVec3d_Normalize(&forceDir);
00531
00532 distToFFCenter = geVec3d_Length(&forceFieldCenterToBBCenter);
00533 if (distToFFCenter < 1.f)
00534 distToFFCenter = 1.f;
00535
00536 if ((boundingBoxCenter.X + boundingBoxScale.X) < (ff->Origin.X - ff->radius)) continue;
00537 if ((boundingBoxCenter.X - boundingBoxScale.X) > (ff->Origin.X + ff->radius)) continue;
00538 if ((boundingBoxCenter.Y + boundingBoxScale.Y) < (ff->Origin.Y - ff->radius)) continue;
00539 if ((boundingBoxCenter.Y - boundingBoxScale.Y) > (ff->Origin.Y + ff->radius)) continue;
00540 if ((boundingBoxCenter.Z + boundingBoxScale.Z) < (ff->Origin.Z - ff->radius)) continue;
00541 if ((boundingBoxCenter.Z - boundingBoxScale.Z) > (ff->Origin.Z + ff->radius)) continue;
00542
00544
00545
00546
00547 switch(ff->falloffType)
00548 {
00549 case FALLOFF_NONE:
00550 forceMultiplier = 1.f;
00551 break;
00552 case FALLOFF_ONE_OVER_D:
00553 forceMultiplier = 1 / distToFFCenter;
00554 break;
00555 case FALLOFF_ONE_OVER_DSQUARED:
00556 forceMultiplier = 1 / (distToFFCenter * distToFFCenter);
00557 break;
00558 default:
00559 forceMultiplier = 1.f;
00560 }
00561
00562 forceMagnitude = ff->strength * forceMultiplier * 1000.f;
00563
00564 geVec3d_Scale(&forceDir, forceMagnitude, &forceToApply);
00565
00566 geVec3d_Scale(&forceToApply, Time, &impulse);
00567 geVec3d_Add(&impulse, &Player->Velocity, &Player->Velocity);
00568 }
00569 }
00570 #endif
00571
00572
00573 for (HitCount=0 ; HitCount<NumHits ; HitCount++)
00574 {
00575 float Fd, Bd;
00576
00577
00578 Pos = Player->XForm.Translation;
00579 geVec3d_AddScaled(&Pos, &Player->Velocity, TimeLeft, &NewPos);
00580
00581
00582 if (geWorld_GetContents(World, &Pos, &Mins, &Maxs, GE_COLLIDE_MODELS, 0, NULL, NULL, &Contents))
00583 {
00584 if (Contents.Contents & GE_CONTENTS_SOLID)
00585 {
00586 if (geWorld_GetContents(World, &NewPos, &Mins, &Maxs, GE_COLLIDE_MODELS, 0, NULL, NULL, &Contents))
00587 {
00588 if (Contents.Contents & GE_CONTENTS_SOLID)
00589 {
00590 geVec3d_Copy(&Player->LastGoodPos, &Player->XForm.Translation);
00591 geVec3d_Clear(&Player->Velocity);
00592 return GE_TRUE;
00593 }
00594 }
00595 }
00596 }
00597
00598 if (!geWorld_Collision(World, &Mins, &Maxs, &Pos, &NewPos, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS, 0, NULL, NULL, &Collision))
00599 return GE_TRUE;
00600
00601 if (Collision.Plane.Normal.Y > 0.7f)
00602 {
00603 if (Player->State == PSTATE_InAir)
00604 Player->State = PSTATE_Normal;
00605 else if (Player->State == PSTATE_Dead)
00606 Player->State = PSTATE_DeadOnGround;
00607
00608 if (Collision.Model)
00609 {
00610 GPlayer *Target;
00611 Target = (GPlayer*)geWorld_ModelGetUserData(Collision.Model);
00612 if (Target && Target->Trigger && Target->ViewFlags & VIEW_TYPE_STANDON)
00613 Target->Trigger(VSI, Target, Player, NULL);
00614 }
00615 }
00616
00617 if (Collision.Model)
00618 {
00619 GPlayer *Target;
00620 #pragma message ("Use: GenVSI_ModelToPlayer...")
00621 Target = (GPlayer*)geWorld_ModelGetUserData(Collision.Model);
00622 if (Target && Target->Trigger && Target->ViewFlags & VIEW_TYPE_PHYSOB)
00623 Target->Trigger(VSI, Target, Player, (void*)&Collision);
00624 }
00625
00626 if (Collision.Actor)
00627 {
00628 geVec3d_Copy(&Player->LastGoodPos, &Player->XForm.Translation);
00629 geVec3d_Clear(&Player->Velocity);
00630 return GE_TRUE;
00631 }
00632
00633
00634 Fd = geVec3d_DotProduct(&Pos, &Collision.Plane.Normal) - Collision.Plane.Dist;
00635 Bd = geVec3d_DotProduct(&NewPos, &Collision.Plane.Normal) - Collision.Plane.Dist;
00636
00637 Collision.Ratio = Fd / (Fd - Bd);
00638
00639 if (Collision.Ratio > 0.00f)
00640 {
00641
00642 geVec3d_Copy(&Collision.Impact, &Player->XForm.Translation);
00643
00644 geVec3d_Copy(&Player->Velocity, &OriginalVelocity);
00645 NumPlanes = 0;
00646 }
00647
00648 if (!Collision.Plane.Normal.Y)
00649 {
00650 if (MovePlayerUpStep(VSI, Player, &Collision))
00651 {
00652 continue;
00653 }
00654 }
00655
00656
00657
00658
00659 if (NumPlanes >= MAX_CLIP_PLANES)
00660 {
00661 GenVSI_ConsolePrintf(VSI, "MAX_CLIP_PLANES!!!\n");
00662 geVec3d_Clear(&Player->Velocity);
00663 return GE_TRUE;
00664 }
00665
00666
00667 geVec3d_Copy (&Collision.Plane.Normal, &Planes[NumPlanes]);
00668 NumPlanes++;
00669
00670
00671
00672
00673 for (i=0 ; i<NumPlanes ; i++)
00674 {
00675 ReflectVelocity(&OriginalVelocity, &Planes[i], &NewVelocity, BounceScale);
00676
00677 for (j=0 ; j<NumPlanes ; j++)
00678 {
00679 if (j != i)
00680 {
00681 if (geVec3d_DotProduct(&NewVelocity, &Planes[j]) < 0.0f)
00682 break;
00683 }
00684 }
00685 if (j == NumPlanes)
00686 break;
00687 }
00688
00689 if (i != NumPlanes)
00690 {
00691 geVec3d_Copy(&NewVelocity, &Player->Velocity);
00692 }
00693 else
00694 {
00695 if (NumPlanes != 2)
00696 {
00697
00698 geVec3d_Clear(&Player->Velocity);
00699 return GE_TRUE;
00700 }
00701
00702
00703 geVec3d_CrossProduct(&Planes[0], &Planes[1], &Dir);
00704 Dist = geVec3d_DotProduct(&Dir, &Player->Velocity);
00705 geVec3d_Scale(&Dir, Dist, &Player->Velocity);
00706 }
00707
00708
00709
00710
00711 if (!AllowBounce && geVec3d_DotProduct (&Player->Velocity, &PrimalVelocity) <= 0.0f)
00712 {
00713 geVec3d_Clear(&Player->Velocity);
00714 return GE_TRUE;
00715 }
00716 }
00717 return GE_TRUE;
00718 }
00719
00720
00721
00722
00723
00724 geBoolean PlayerPhysics(GenVSI *VSI,
00725 void *PlayerData,
00726 float GroundFriction,
00727 float AirFriction,
00728 float LiquidFriction,
00729 float Gravity,
00730 float BounceScale,
00731 geBoolean AllowBounce,
00732 float Time)
00733 {
00734 float Speed;
00735 GPlayer *Player;
00736
00737 Player = (GPlayer*)PlayerData;
00738
00739 #ifndef FLY_MODE
00740 Player->LastGoodPos = Player->XForm.Translation;
00741
00742
00743 switch (Player->State)
00744 {
00745 case PSTATE_InLava:
00746 case PSTATE_InWater:
00747 Player->Velocity.Y -= PLAYER_GRAVITY*Time*0.05f;
00748 break;
00749
00750 default:
00751 Player->Velocity.Y -= PLAYER_GRAVITY*Time;
00752 break;
00753 }
00754
00755 CheckVelocity(VSI, Player, BounceScale, AllowBounce, Time);
00756
00757 SqueezeVector(&Player->Velocity, 0.2f);
00758 geVec3d_AddScaled(&Player->XForm.Translation, &Player->Velocity, Time, &Player->XForm.Translation);
00759
00760 CheckPlayer(VSI, Player);
00761 #else // Fly through walls
00762 Player->State = PSTATE_InAir;
00763 SqueezeVector(&Player->Velocity, 0.2f);
00764 geVec3d_AddScaled(&Player->XForm.Translation, &Player->Velocity, Time, &Player->XForm.Translation);
00765 #endif
00766
00767 Speed = geVec3d_Length(&Player->Velocity);
00768
00769
00770 if (Speed > 0.001)
00771 {
00772 float NewSpeed;
00773
00774 if (Player->State == PSTATE_Normal || Player->State == PSTATE_DeadOnGround)
00775 NewSpeed = Speed - Time*Speed*PLAYER_GROUND_FRICTION;
00776 else if (Player->State == PSTATE_InAir || Player->State == PSTATE_Dead)
00777 NewSpeed = Speed - Time*Speed*PLAYER_AIR_FRICTION;
00778 else if (PlayerLiquid(Player))
00779 NewSpeed = Speed - Time*Speed*PLAYER_LIQUID_FRICTION;
00780
00781 if (NewSpeed < 0.0f)
00782 NewSpeed = 0.0f;
00783
00784 NewSpeed /= Speed;
00785
00786
00787 geVec3d_Scale(&Player->Velocity, NewSpeed, &Player->Velocity);
00788 }
00789
00790 UpdatePlayerContents(VSI, Player, Time);
00791
00792 return GE_TRUE;
00793 }
00794
00795
00796
00797
00798 geBoolean UpdatePlayerContents(GenVSI *VSI, void *PlayerData, float Time)
00799 {
00800 GPlayer *Player;
00801 geWorld *World;
00802 GE_Contents Contents;
00803
00804 World = GenVSI_GetWorld(VSI);
00805
00806 assert(World);
00807
00808 Player = (GPlayer*)PlayerData;
00809
00810 if (geWorld_GetContents(World, &Player->XForm.Translation, &Player->Mins, &Player->Maxs, GE_COLLIDE_MODELS, 0, NULL, NULL, &Contents))
00811 {
00812
00813 if (Contents.Contents & CONTENTS_WATER)
00814 {
00815 Player->State = PSTATE_InWater;
00816 }
00817 else if (Contents.Contents & CONTENTS_LAVA)
00818 {
00819 Player->State = PSTATE_InLava;
00820 }
00821 else if (PlayerLiquid(Player))
00822 Player->State = PSTATE_Normal;
00823 }
00824 else if (PlayerLiquid(Player))
00825 Player->State = PSTATE_Normal;
00826
00827 return GE_TRUE;
00828 }
00829
00830 geBoolean PlayerDead(GPlayer *Player)
00831 {
00832 assert(Player);
00833
00834 if (Player->State == PSTATE_Dead)
00835 return GE_TRUE;
00836
00837 if (Player->State == PSTATE_DeadOnGround)
00838 return GE_TRUE;
00839
00840 return GE_FALSE;
00841 }
00842
00843 static int32 Hack2;
00844
00845
00846
00847
00848 geBoolean Client_Control(GenVSI *VSI, void *PlayerData, float Time)
00849 {
00850 geVec3d LVect, InVect;
00851 float Speed;
00852 GE_Contents Contents;
00853 geVec3d CMins, CMaxs;
00854 float MoveSpeed;
00855 geBoolean DoWalk = GE_FALSE;
00856 geXForm3d XForm;
00857 GPlayer *Player;
00858 GenVSI_CMove *Move;
00859 geWorld *World;
00860 uint32 ColFlags;
00861 CData Data;
00862
00863 Player = (GPlayer*)PlayerData;
00864
00865 assert(Player);
00866
00867 assert(Player->ClientHandle != CLIENT_NULL_HANDLE);
00868
00869
00870
00871
00872
00873 if (PlayerDead(Player))
00874 return GE_TRUE;
00875
00876 if (IsKeyDown('L'))
00877 {
00878 GenVSI_SetWorld(VSI, SetupWorldCB, ShutdownWorldCB, "Levels\\GenVs.Bsp");
00879 return GE_TRUE;
00880 }
00881
00882
00883 Move = GenVSI_GetClientMove(VSI, Player->ClientHandle);
00884
00885 if (!Move)
00886 return GE_TRUE;
00887
00888 assert(Move);
00889
00890 Player->Time += Time;
00891
00892
00893 SetupPlayerXForm(VSI, Player, Time);
00894
00895 geXForm3d_SetYRotation(&XForm, Move->Angles.Y);
00896
00897 geXForm3d_GetLeft(&XForm, &LVect);
00898
00899 #ifdef FLY_MODE
00900 geXForm3d_GetIn(&Player->XForm, &InVect);
00901 #else
00902 if (PlayerLiquid(Player))
00903 geXForm3d_GetIn(&Player->XForm, &InVect);
00904 else
00905 geXForm3d_GetIn(&XForm, &InVect);
00906 #endif
00907
00908
00909 if (Move->ButtonBits & HOST_BUTTON_FIRE)
00910 {
00911 uint16 Amount;
00912 geBoolean Has;
00913
00914 Player->CurrentWeapon = Move->Weapon;
00915
00916 assert(Player->CurrentWeapon >= 0 && Player->CurrentWeapon <= 3);
00917
00918 assert(Player->ClientHandle != CLIENT_NULL_HANDLE);
00919
00920 FireWeapon(VSI, PlayerData, Time);
00921
00922 assert(Player->Inventory[Player->CurrentWeapon] >= 0 && Player->Inventory[Player->CurrentWeapon] < 65535);
00923
00924 Amount = (uint16)Player->Inventory[Player->CurrentWeapon];
00925 Has = Player->InventoryHas[Player->CurrentWeapon];
00926
00927 GenVSI_SetClientInventory(VSI, Player->ClientHandle, Player->CurrentWeapon, Amount, Has);
00928 }
00929
00930 MoveSpeed = Time;
00931
00932 if (Player->State != PSTATE_Normal)
00933 MoveSpeed *= 0.15f;
00934
00935
00936 if (Move->ForwardSpeed)
00937 {
00938 geVec3d_MA(&Player->Velocity, Move->ForwardSpeed*MoveSpeed, &InVect, &Player->Velocity);
00939 }
00940
00941 if (Move->ButtonBits & HOST_BUTTON_LEFT)
00942 geVec3d_MA(&Player->Velocity, PLAYER_SIDE_SPEED*MoveSpeed, &LVect, &Player->Velocity);
00943
00944 if (Move->ButtonBits & HOST_BUTTON_RIGHT)
00945 geVec3d_MA(&Player->Velocity, -PLAYER_SIDE_SPEED*MoveSpeed, &LVect, &Player->Velocity);
00946
00947 if ((Move->ButtonBits & HOST_BUTTON_JUMP) && (PlayerLiquid(Player) || Player->State == PSTATE_Normal))
00948 {
00949 GenVSI_PlaySound(VSI, SOUND_INDEX_JUMP, &Player->XForm.Translation);
00950
00951 if (Player->State == PSTATE_Normal)
00952 Player->Velocity.Y += PLAYER_JUMP_THRUST;
00953 else
00954 Player->Velocity.Y += PLAYER_JUMP_THRUST*0.2f;
00955 }
00956
00957
00958 PlayerPhysics(VSI, Player, PLAYER_GROUND_FRICTION, PLAYER_AIR_FRICTION, PLAYER_LIQUID_FRICTION, PLAYER_GRAVITY, 1.0f, GE_FALSE, Time);
00959
00960 World = GenVSI_GetWorld(VSI);
00961
00962 assert(World);
00963
00964 ColFlags = GE_COLLIDE_MODELS;
00965
00966 if (VSI->Mode == MODE_Server)
00967 {
00968 if (!PlayerDead(Player) && Player->Roll > 0.0f)
00969 Player->Roll -= Time;
00970
00971 #ifndef FLY_MODE
00972 if (Player->State == PSTATE_InLava)
00973 {
00974 if (Player->Roll <= 0.0f)
00975 {
00976 DammagePlayer(VSI, NULL, Player, 20, 0.0f, Time);
00977 Player->Roll = 0.5f;
00978 }
00979 }
00980 #endif
00981
00982
00983 CMins = Player->Mins;
00984 CMaxs = Player->Maxs;
00985
00986 CMins.X -= 100;
00987 CMins.Y -= 10;
00988 CMins.Z -= 100;
00989 CMaxs.X += 100;
00990 CMaxs.Y += 10;
00991 CMaxs.Z += 100;
00992
00993 if (geWorld_GetContents(World, &Player->XForm.Translation, &CMins, &CMaxs, GE_COLLIDE_MODELS, 0, NULL, NULL, &Contents))
00994 {
00995 if (Contents.Model)
00996 {
00997 GPlayer *TPlayer;
00998
00999 TPlayer = (GPlayer*)geWorld_ModelGetUserData(Contents.Model);
01000
01001 if (TPlayer)
01002 {
01003 Hack2 = 0;
01004 }
01005 if (TPlayer && TPlayer->Trigger && TPlayer->ViewFlags & VIEW_TYPE_TOUCH)
01006 {
01007 TPlayer->Trigger(VSI, TPlayer, Player, NULL);
01008 }
01009 }
01010 }
01011
01012 Data.VSI = VSI;
01013 Data.Player = Player;
01014
01015 if (geWorld_GetContents(World, &Player->XForm.Translation, &CMins, &CMaxs, GE_COLLIDE_ACTORS, 0xffffffff, SelfCollisionCB, &Data, &Contents))
01016
01017 {
01018 if (Contents.Actor)
01019 {
01020 GPlayer *TPlayer;
01021 static int32 HackV;
01022
01023
01024
01025 TPlayer = (GPlayer*)GenVSI_ActorToPlayer(VSI, Contents.Actor);
01026
01027 if (TPlayer && TPlayer->Trigger)
01028 {
01029 TPlayer->Trigger(VSI, TPlayer, Player, NULL);
01030 }
01031 }
01032 }
01033
01034 }
01035
01036 Speed = geVec3d_Length(&Player->Velocity);
01037
01038 if ((Move->ButtonBits & HOST_BUTTON_LEFT)
01039 || (Move->ButtonBits & HOST_BUTTON_RIGHT)
01040 || Move->ForwardSpeed)
01041 {
01042 if (Player->MotionIndex != ACTOR_MOTION_PLAYER_RUN)
01043 Player->FrameTime = 0.0f;
01044
01045 Player->MotionIndex = ACTOR_MOTION_PLAYER_RUN;
01046 DoWalk = GE_TRUE;
01047 }
01048
01049 if (Speed > 0.1f && DoWalk)
01050 {
01051 if (Player->MotionIndex == ACTOR_MOTION_PLAYER_RUN)
01052 {
01053 Speed*=0.004f;
01054
01055 if (Move->ForwardSpeed<0)
01056 Speed *= -1.0f;
01057 }
01058 else
01059 Speed = 1.0f;
01060
01061 if (AnimatePlayer(VSI, Player, Player->MotionIndex, Time*Speed, GE_TRUE))
01062 {
01063 if (Player->MotionIndex != ACTOR_MOTION_PLAYER_RUN)
01064 Player->FrameTime = 0.0f;
01065
01066 Player->MotionIndex = ACTOR_MOTION_PLAYER_RUN;
01067 }
01068 }
01069 else
01070 {
01071 if (Player->MotionIndex != ACTOR_MOTION_PLAYER_IDLE)
01072 {
01073 Player->MotionIndex = ACTOR_MOTION_PLAYER_IDLE;
01074 Player->FrameTime = 0.0f;
01075 }
01076
01077 AnimatePlayer(VSI, Player, Player->MotionIndex, Time, GE_TRUE);
01078 }
01079
01080
01081 SetupPlayerXForm(VSI, Player, Time);
01082
01083 Player->VPos = Player->XForm.Translation;
01084
01085 return GE_TRUE;
01086 }
01087
01088
01089
01090
01091 geBoolean Player_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01092 {
01093 PlayerStart *Ps;
01094 GPlayer *Player;
01095
01096 Player = (GPlayer*)PlayerData;
01097
01098 Player->Control = NULL;
01099 Player->Trigger = NULL;
01100 Player->Blocked = NULL;
01101 Player->Time = 0.0f;
01102
01103 if (ClassData == NULL)
01104 {
01105 GenVS_Error("Player_Spawn: entity missing class data ('%s')\n",EntityName);
01106 }
01107
01108 Ps = (PlayerStart*)ClassData;
01109
01110 geXForm3d_SetIdentity(&Player->XForm);
01111 geXForm3d_SetTranslation(&Player->XForm, Ps->Origin.X, Ps->Origin.Y, Ps->Origin.Z);
01112
01113 Player->VPos = Player->XForm.Translation;
01114
01115 return GE_TRUE;
01116 }
01117
01118
01119
01120
01121 static geBoolean Door_Control(GenVSI *VSI, void *PlayerData, float Time)
01122 {
01123 geWorld_Model *Model;
01124 geMotion *Motion;
01125 float StartTime, EndTime, NewTime;
01126 geXForm3d DestXForm;
01127 gePath *Path;
01128 GPlayer *Player;
01129 geWorld *World;
01130
01131 Player = (GPlayer*)PlayerData;
01132
01133 if (Player->State != PSTATE_Opened)
01134 return GE_TRUE;
01135
01136 World = GenVSI_GetWorld(VSI);
01137
01138 assert(World);
01139
01140 Model = Player->Model;
01141
01142 assert(Model);
01143
01144 Motion = geWorld_ModelGetMotion(Model);
01145 assert(Motion);
01146
01147 NewTime = Player->FrameTime + Time;
01148
01149 Path = geMotion_GetPath(Motion, 0);
01150
01151 assert(Path);
01152
01153 geMotion_GetTimeExtents(Motion, &StartTime , &EndTime);
01154
01155 if (NewTime >= EndTime)
01156 {
01157 NewTime = StartTime;
01158 Player->State = PSTATE_Closed;
01159
01160 Player->ViewFlags &= ~VIEW_TYPE_MODEL_OPEN;
01161 }
01162
01163
01164 gePath_Sample(Path, NewTime, &DestXForm);
01165
01166
01167 if (GenVSI_MovePlayerModel(VSI, Player, &DestXForm))
01168 {
01169 Player->XForm = DestXForm;
01170
01171 Player->FrameTime = NewTime;
01172 }
01173
01174
01175
01176
01177 return GE_TRUE;
01178 }
01179
01180
01181
01182
01183 static geBoolean Plat_Control(GenVSI *VSI, void *PlayerData, float Time)
01184 {
01185 geWorld_Model *Model;
01186 geMotion *Motion;
01187 float StartTime, EndTime, NewTime;
01188 geXForm3d DestXForm;
01189 gePath *Path;
01190 GPlayer *Player;
01191 geWorld *World;
01192 MovingPlat *Plat;
01193
01194 Player = (GPlayer*)PlayerData;
01195
01196 if (Player->State != PSTATE_Opened)
01197 return GE_TRUE;
01198
01199 World = GenVSI_GetWorld(VSI);
01200
01201 assert(World);
01202
01203 Model = Player->Model;
01204
01205 assert(Model);
01206
01207 Motion = geWorld_ModelGetMotion(Model);
01208 assert(Motion);
01209
01210 NewTime = Player->FrameTime + Time;
01211
01212 Path = geMotion_GetPath(Motion, 0);
01213
01214 assert(Path);
01215
01216 geMotion_GetTimeExtents(Motion, &StartTime , &EndTime);
01217
01218 if (NewTime >= EndTime)
01219 {
01220 NewTime = StartTime;
01221 Player->State = PSTATE_Closed;
01222
01223 Player->ViewFlags &= ~VIEW_TYPE_MODEL_OPEN;
01224
01225 Plat = (MovingPlat*)Player->ClassData;
01226
01227
01228
01229
01230
01231
01232 }
01233
01234
01235 gePath_Sample(Path, NewTime, &DestXForm);
01236
01237
01238 if (GenVSI_MovePlayerModel(VSI, Player, &DestXForm))
01239 {
01240 Player->XForm = DestXForm;
01241
01242 Player->FrameTime = NewTime;
01243 }
01244
01245
01246
01247
01248 return GE_TRUE;
01249 }
01250
01251
01252
01253
01254 static geBoolean Door_Trigger(GenVSI *VSI, void *PlayerData, void *TargetData, void* data)
01255 {
01256 GPlayer *Player, *Target;
01257
01258 Player = (GPlayer*)PlayerData;
01259 Target = (GPlayer*)TargetData;
01260
01261 if (Player->State == PSTATE_Opened)
01262 return GE_TRUE;
01263
01264 Player->State = PSTATE_Opened;
01265 Player->FrameTime = 0.0f;
01266
01267 assert(Player->Model);
01268
01269 Player->ViewFlags |= VIEW_TYPE_MODEL_OPEN;
01270
01271 GenVSI_PlaySound(VSI, 2, &Player->XForm.Translation);
01272
01273 return GE_TRUE;
01274 }
01275
01276
01277
01278
01279 static geBoolean Door_Blocked(GenVSI *VSI, void *PlayerData, void *TargetData)
01280 {
01281 return GE_TRUE;
01282 }
01283
01284
01285
01286
01287 static geBoolean Door_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01288 {
01289 geWorld_Model *Model;
01290 geMotion *Motion;
01291 gePath *Path;
01292 GPlayer *Player;
01293 Door *FuncDoor;
01294 geWorld *World;
01295
01296 Player = (GPlayer*)PlayerData;
01297
01298 Player->Control = Door_Control;
01299 Player->Trigger = Door_Trigger;
01300 Player->Blocked = Door_Blocked;
01301
01302 Player->ControlIndex = 1;
01303
01304
01305 Player->Time = 0.0f;
01306
01307
01308
01309 FuncDoor = (Door*)ClassData;
01310 Player->VPos = FuncDoor->Origin;
01311
01312 Model = FuncDoor->Model;
01313
01314 if (!Model)
01315 {
01316 GenVS_Error( "Door_Spawn: No model for entity:%s.\n",EntityName);
01317 return GE_FALSE;
01318 }
01319
01320 World = GenVSI_GetWorld(VSI);
01321
01322
01323
01324
01325 Motion = geWorld_ModelGetMotion(Model);
01326
01327 if (!Motion)
01328 {
01329 GenVS_Error( "Door_Spawn: No motion for model ('%s').\n",EntityName);
01330 return GE_FALSE;
01331 }
01332
01333 Path = geMotion_GetPath(Motion, 0);
01334
01335 if (!Path)
01336 {
01337 GenVS_Error( "Door_Spawn: No path for model motion ('%s').\n",EntityName);
01338 return GE_FALSE;
01339 }
01340
01341
01342 gePath_Sample(Path, 0.0f, &Player->XForm);
01343
01344 Player->ViewFlags = VIEW_TYPE_MODEL | VIEW_TYPE_TOUCH;
01345 Player->ViewIndex = GenVSI_ModelToViewIndex(VSI, Model);
01346
01347
01348
01349 GenVSI_RegisterPlayerModel(VSI, Player, Model);
01350
01351 return GE_TRUE;
01352 }
01353
01354
01355
01356 static geBoolean Plat_Trigger(GenVSI *VSI, void *PlayerData, void *TargetData, void* data)
01357 {
01358 geVec3d Pos;
01359 GPlayer *Player, *Target;
01360
01361 Player = (GPlayer*)PlayerData;
01362 Target = (GPlayer*)TargetData;
01363
01364 if (Player->State == PSTATE_Opened)
01365 return GE_TRUE;
01366
01367 Player->State = PSTATE_Opened;
01368 Player->FrameTime = 0.0f;
01369
01370 if (Target)
01371 {
01372 Pos = Target->XForm.Translation;
01373 }
01374 else
01375 {
01376 geWorld *World;
01377
01378 World = GenVSI_GetWorld(VSI);
01379
01380 assert(World);
01381
01382 geWorld_GetModelRotationalCenter(World, Player->Model, &Pos);
01383 geVec3d_Add(&Pos, &Player->XForm.Translation, &Pos);
01384 }
01385
01386
01387 GenVSI_PlaySound(VSI, 2, &Pos);
01388
01389 return GE_TRUE;
01390 }
01391
01392
01393
01394
01395 static geBoolean Plat_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01396 {
01397 geWorld_Model *Model;
01398 geMotion *Motion;
01399 gePath *Path;
01400 GPlayer *Player;
01401 MovingPlat *Plat;
01402 geWorld *World;
01403
01404 Player = (GPlayer*)PlayerData;
01405
01406 Player->Control = Plat_Control;
01407 Player->Trigger = Plat_Trigger;
01408 Player->Time = 0.0f;
01409
01410 Player->ControlIndex = 3;
01411
01412
01413
01414 Plat = (MovingPlat*)ClassData;
01415
01416 Player->VPos = Plat->Origin;
01417
01418
01419 Model = Plat->Model;
01420
01421 if (!Model)
01422 {
01423 GenVS_Error( "Plat_Spawn: No model for entity ('%s').\n",EntityName);
01424 return GE_FALSE;
01425 }
01426
01427 World = GenVSI_GetWorld(VSI);
01428
01429
01430
01431
01432 Motion = geWorld_ModelGetMotion(Model);
01433
01434 if (!Motion)
01435 {
01436 GenVS_Error( "Plat_Spawn: No motion for model ('%s').\n",EntityName);
01437 return GE_FALSE;
01438 }
01439
01440 Path = geMotion_GetPath(Motion, 0);
01441
01442 if (!Path)
01443 {
01444 GenVS_Error( "Plat_Spawn: No path for model motion ('%s').\n",EntityName);
01445 return GE_FALSE;
01446 }
01447
01448
01449 gePath_Sample(Path, 0.0f, &Player->XForm);
01450
01451 Player->ViewFlags = VIEW_TYPE_MODEL | VIEW_TYPE_STANDON;
01452 Player->ViewIndex = GenVSI_ModelToViewIndex(VSI, Model);
01453
01454
01455
01456 GenVSI_RegisterPlayerModel(VSI, Player, Model);
01457
01458
01459
01460
01461
01462
01463 return GE_TRUE;
01464 }
01465
01468
01469
01470
01471
01472 static geBoolean PhysicsObject_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01473 {
01474 geWorld_Model *Model;
01475 GPlayer *Player;
01476 PhysicsObject *po;
01477 geWorld *World;
01478 geVec3d Mins;
01479 geVec3d Maxs;
01480
01481 Player = (GPlayer*)PlayerData;
01482
01483 Player->Control = PhysicsObject_Control;
01484 Player->Trigger = PhysicsObject_Trigger;
01485
01486 Player->Time = 0.0f;
01487
01488 po = NULL;
01489 po = (PhysicsObject*)ClassData;
01490
01491 if (po == NULL)
01492 {
01493 GenVS_Error( "PhysicsObject_Spawn: NULL class data for physics entity '%s'. (at coordinates: x=%f y=%f z=%f)\n",
01494 EntityName,po->Origin.X,po->Origin.Y,po->Origin.Z);
01495 return GE_FALSE;
01496 }
01497
01498 Model = po->Model;
01499
01500 Player->VPos = po->Origin;
01501
01502 if (!Model)
01503 {
01504 GenVS_Error( "PhysicsObject_Spawn: No model for physics entity '%s'. (at coordinates: x=%f y=%f z=%f)\n",
01505 EntityName,po->Origin.X,po->Origin.Y,po->Origin.Z);
01506 return GE_FALSE;
01507 }
01508
01509 World = GenVSI_GetWorld(VSI);
01510
01512
01513 Player->ViewFlags = VIEW_TYPE_MODEL | VIEW_TYPE_PHYSOB;
01514 Player->ViewIndex = GenVSI_ModelToViewIndex(VSI, Model);
01515
01516
01517
01518 #define PHYSOB_MAX_DAMPING (1.f)
01519 #define PHYSOB_MIN_DAMPING (0.f)
01520
01521 if (po->linearDamping < PHYSOB_MIN_DAMPING)
01522 po->linearDamping = PHYSOB_MIN_DAMPING;
01523
01524 else if (po->linearDamping > PHYSOB_MAX_DAMPING)
01525 po->linearDamping = PHYSOB_MAX_DAMPING;
01526
01527 if (po->angularDamping < PHYSOB_MIN_DAMPING)
01528 po->angularDamping = PHYSOB_MIN_DAMPING;
01529
01530 else if (po->angularDamping > PHYSOB_MAX_DAMPING)
01531 po->angularDamping = PHYSOB_MAX_DAMPING;
01532
01533
01534
01535 geWorld_ModelGetBBox(World, po->Model, &Mins, &Maxs);
01536
01537 #pragma message("Mins / maxs should be OK in the next build")
01538
01539 po->stateInfo = gePhysicsObject_Create(&po->Origin,
01540 po->mass,
01541 po->isAffectedByGravity,
01542 po->respondsToForces,
01543 po->linearDamping,
01544 po->angularDamping,
01545 &Mins,
01546 &Maxs,
01547 0.01f);
01548
01549
01550 if (po->stateInfo == NULL)
01551 {
01552 GenVS_Error( "PhysicsObject_Spawn: gePhysicsObject_Create failed for physics entity '%s'\n",EntityName);
01553 return GE_FALSE;
01554 }
01555
01556 Player->userData = po->stateInfo;
01557
01558
01559
01560
01561 GenVSI_RegisterPlayerModel(VSI, Player, Model);
01562
01563 return GE_TRUE;
01564 }
01565
01566 static void PhysicsObject_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData)
01567 {
01568 GPlayer *Player;
01569 PhysicsObject *po;
01570
01571 Player = (GPlayer*)PlayerData;
01572 po = (PhysicsObject*)ClassData;
01573
01574 if (po)
01575 if (po->stateInfo)
01576 {
01577 gePhysicsObject_Destroy(&po->stateInfo);
01578 }
01579 }
01580
01581 static geBoolean PhysicsObject_Trigger(GenVSI *VSI, void *PlayerData, GPlayer *Target, void *data)
01582 {
01584
01585
01586
01587
01588 GPlayer *Player;
01589 PhysicsObject* poPtr;
01590 gePhysicsObject* podPtr;
01591 GE_Collision* collisionInfo;
01592 float velMagN;
01593 geVec3d radiusVector;
01594 geVec3d force;
01595 geVec3d poCOM;
01596 int activeConfigIndex;
01597 float scale;
01598
01599 Player = (GPlayer*)PlayerData;
01600 poPtr = (PhysicsObject*)Player->ClassData;
01601 podPtr = (gePhysicsObject*)Player->userData;
01602 collisionInfo = (GE_Collision*)data;
01603
01604
01605 scale = gePhysicsObject_GetPhysicsScale(podPtr);
01606 activeConfigIndex = gePhysicsObject_GetActiveConfig(podPtr);
01607 gePhysicsObject_GetLocationInEditorSpace(podPtr, &poCOM, activeConfigIndex);
01608 geVec3d_Subtract(&collisionInfo->Impact, &poCOM, &radiusVector);
01609
01610 velMagN = geVec3d_DotProduct(&Target->Velocity, &collisionInfo->Plane.Normal);
01611
01612 geVec3d_Scale(&collisionInfo->Plane.Normal, velMagN * 4.f, &force);
01613 geVec3d_Scale(&radiusVector, scale, &radiusVector);
01614
01615 gePhysicsObject_ApplyGlobalFrameForce(podPtr, &force, &radiusVector, GE_TRUE, activeConfigIndex);
01616
01617 return GE_TRUE;
01618
01619 }
01620
01621 geVec3d bboxVerts[8] =
01622 {
01623 {-1.0f, 1.0f, 1.0f},
01624 {-1.0f, -1.0f, 1.0f},
01625 {1.0f, -1.0f, 1.0f},
01626 {1.0f, 1.0f, 1.0f},
01627 {-1.0f, 1.0f, -1.0f},
01628 {-1.0f, -1.0f, -1.0f},
01629 {1.0f, -1.0f, -1.0f},
01630 {1.0f, 1.0f, -1.0f}
01631 };
01632
01633 #define MIN(a,b) ((a) < (b) ? (a) : (b))
01634 #define MAX(a,b) ((a) > (b) ? (a) : (b))
01635
01636 static geBoolean PhysicsObject_Control(GenVSI* VSI, void* PlayerData, float Time)
01637 {
01638
01639 GPlayer* player;
01640 gePhysicsObject* pod;
01641 int activeConfigIndex;
01642 geXForm3d destXForm;
01643 #if 0
01644 geXForm3d xform;
01645 geWorld* world;
01646 geVec3d bbmin, bbmax, bbdims;
01647 geVec3d tmpVec;
01648 int i;
01649 Matrix33 A;
01650 geVec3d boundingBoxCenter;
01651 geEntity_EntitySet* Set;
01652 geEntity* Entity;
01653 geVec3d boundingBoxScale;
01654 #endif
01655
01657
01659
01660 player = (GPlayer*)PlayerData;
01661 if (player == NULL)
01662 {
01663 GenVS_Error( "PhysicsObject_Control: invalid player.\n");
01664 return GE_FALSE;
01665 }
01666
01667 pod = (gePhysicsObject*)player->userData;
01668 if (pod == NULL)
01669 {
01670 GenVS_Error( "PhysicsObject_Control: pod = NULL.\n");
01671 return GE_FALSE;
01672 }
01673 activeConfigIndex = gePhysicsObject_GetActiveConfig(pod);
01674
01675 #if 0
01676 world = GenVSI_GetWorld(VSI);
01677
01678 geWorld_ModelGetBBox(world, player->Model, &bbmin, &bbmax);
01679
01680 gePhysicsObject_GetLocation(pod, &boundingBoxCenter);
01681
01682 geVec3d_Scale(&bbmin, PHYSOB_SCALE, &bbmin);
01683 geVec3d_Scale(&bbmax, PHYSOB_SCALE, &bbmax);
01684
01685 geVec3d_Subtract(&bbmax, &bbmin, &bbdims);
01686 geVec3d_Scale(&bbdims, 0.5f, &boundingBoxScale);
01687
01688 gePhysicsObject_GetXForm(pod, &xform);
01689 Matrix33_ExtractFromXForm3d(&xform, &A);
01690
01692
01693
01694 Set = NULL;
01695 Set = geWorld_GetEntitySet(world, "ForceField");
01696 if (Set != NULL)
01697 {
01698 for (Entity = geEntity_EntitySetGetNextEntity(Set, NULL);
01699 Entity != NULL;
01700 Entity = geEntity_EntitySetGetNextEntity(Set, Entity))
01701 {
01702 ForceField* ff;
01703 geVec3d vertPos;
01704 float forceMultiplier;
01705 float distToFFCenter;
01706 float forceMagnitude;
01707 geVec3d forceDir;
01708 geVec3d forceToApply, ptOfApplication;
01709 geVec3d ffOriginInPhysicsSpace;
01710
01711 ff = geEntity_GetUserData(Entity);
01712 assert(ff != NULL);
01713
01714 if (! ff->affectsPhysicsObjects)
01715 continue;
01716
01717 for (i = 0; i < 8; i++)
01718 {
01719 tmpVec.X = boundingBoxScale.X * bboxVerts[i].X;
01720 tmpVec.Y = boundingBoxScale.Y * bboxVerts[i].Y;
01721 tmpVec.Z = boundingBoxScale.Z * bboxVerts[i].Z;
01722
01723 Matrix33_MultiplyVec3d(&A, &tmpVec, &vertPos);
01724 geVec3d_Add(&boundingBoxCenter, &vertPos, &vertPos);
01725
01726 geVec3d_Scale(&ff->Origin, PHYSOB_SCALE, &ffOriginInPhysicsSpace);
01727
01728 geVec3d_Subtract(&vertPos, &ffOriginInPhysicsSpace, &forceDir);
01729 distToFFCenter = geVec3d_Length(&forceDir);
01730
01731 if (distToFFCenter > ff->radius) continue;
01732
01733 geVec3d_Normalize(&forceDir);
01734
01736
01737
01738 switch(ff->falloffType)
01739 {
01740 case FALLOFF_NONE:
01741 forceMultiplier = 1.f;
01742 break;
01743 case FALLOFF_ONE_OVER_D:
01744 forceMultiplier = 1 / distToFFCenter;
01745 break;
01746 case FALLOFF_ONE_OVER_DSQUARED:
01747 forceMultiplier = 1 / (distToFFCenter * distToFFCenter);
01748 break;
01749 default:
01750 forceMultiplier = 1.f;
01751 }
01752
01753 forceMagnitude = ff->strength * forceMultiplier * 1000.f * PHYSOB_SCALE;
01754
01755 geVec3d_Scale(&forceDir, forceMagnitude, &forceToApply);
01756 geVec3d_Subtract(&vertPos, &boundingBoxCenter, &ptOfApplication);
01757 gePhysicsObject_ApplyGlobalFrameForce(pod, &forceToApply, &ptOfApplication, GE_TRUE);
01758
01759 }
01760 }
01761 }
01762 #endif
01763
01764
01765 gePhysicsObject_GetXFormInEditorSpace(pod, &destXForm, activeConfigIndex);
01766 if (GenVSI_MovePlayerModel(VSI, player, &destXForm))
01767 {
01768
01769 geXForm3d_Copy(&destXForm, &player->XForm);
01770 }
01771
01772 return GE_TRUE;
01773 }
01774
01778
01779
01780
01781 static geBoolean PhysicsJoint_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01782 {
01783 GPlayer *Player;
01784 PhysicsJoint *ij;
01785
01786 Player = (GPlayer*)PlayerData;
01787
01788 ij = NULL;
01789 ij = (PhysicsJoint*)ClassData;
01790
01791 if (ij == NULL)
01792 {
01793 GenVS_Error( "PhysicsJoint_Spawn: NULL Class Data ('%s').\n",EntityName);
01794 return GE_FALSE;
01795 }
01796
01797 Player->ViewFlags = VIEW_TYPE_LOCAL;
01798
01799 #define JOINT_MIN_ASSEMBLY_RATE (0.01f)
01800 #define JOINT_MAX_ASSEMBLY_RATE (1.f)
01801
01802 if (ij->assemblyRate < JOINT_MIN_ASSEMBLY_RATE)
01803 ij->assemblyRate = JOINT_MIN_ASSEMBLY_RATE;
01804
01805 else if (ij->assemblyRate > JOINT_MAX_ASSEMBLY_RATE)
01806 ij->assemblyRate = JOINT_MAX_ASSEMBLY_RATE;
01807
01808 ij->jointData = NULL;
01809 ij->jointData = gePhysicsJoint_Create(ij->jointType,
01810 &ij->Origin,
01811 ij->assemblyRate,
01812 ij->physicsObject1 ? ij->physicsObject1->stateInfo : NULL,
01813 ij->physicsObject2 ? ij->physicsObject2->stateInfo : NULL,
01814 0.01f);
01815
01816 if (ij->jointData == NULL)
01817 {
01818 GenVS_Error( "PhysicsJoint_Spawn: Couldn't Create('%s').\n",EntityName);
01819 return GE_FALSE;
01820 }
01821
01822 return GE_TRUE;
01823 }
01824
01825
01826
01827 static void PhysicsJoint_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData)
01828 {
01829 GPlayer *Player;
01830 PhysicsJoint *ij;
01831
01832 Player = (GPlayer*)PlayerData;
01833
01834 ij = NULL;
01835 ij = (PhysicsJoint*)ClassData;
01836
01837 assert(ij->jointData);
01838
01839 gePhysicsJoint_Destroy(&ij->jointData);
01840 }
01841
01842
01843
01844 static geBoolean PhysicsJoint_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data)
01845 {
01846 return GE_TRUE;
01847 }
01848
01849 static geBoolean PhysicsJoint_Control(GenVSI* VSI, void* PlayerData, float Time)
01850 {
01851 return GE_TRUE;
01852 }
01853
01854
01858
01859
01860
01861 static geBoolean PhysicalSystem_Spawn(GenVSI *VSI, void *PlayerData, void *ClassData, char *EntityName)
01862 {
01863 GPlayer *Player;
01864 PhysicalSystem *ips;
01865 PhysicsObject *Object;
01866 PhysicsObject *Object2;
01867 PhysicsJoint *PhysicsJoint;
01868
01869 Player = NULL;
01870 Player = (GPlayer*)PlayerData;
01871 if (Player == NULL)
01872 {
01873 GenVS_Error( "PhysicalSystem_Spawn: NULL Player ('%s').\n",EntityName);
01874 return GE_FALSE;
01875 }
01876
01877 Player->Control = PhysicalSystem_Control;
01878
01879 if (Player->Control == NULL)
01880 {
01881 GenVS_Error( "PhysicalSystem_Spawn: NULL Player control ('%s').\n",EntityName);
01882 return GE_FALSE;
01883 }
01884
01885 Player->Blocked = NULL;
01886 Player->Trigger = NULL;
01887
01888 Player->ViewFlags = VIEW_TYPE_LOCAL;
01889 Player->ViewIndex = VIEW_INDEX_NONE;
01890
01891 geXForm3d_SetIdentity(&Player->XForm);
01892
01893 ips = NULL;
01894 ips = (PhysicalSystem*)ClassData;
01895
01896 if (ips == NULL)
01897 {
01898 GenVS_Error( "PhysicalSystem_Spawn: NULL Class Data ('%s').\n",EntityName);
01899 return GE_FALSE;
01900 }
01901
01902 ips->physsysData = NULL;
01903
01904 ips->physsysData = gePhysicsSystem_Create();
01905 if (ips->physsysData == NULL)
01906 {
01907 GenVS_Error( "PhysicalSystem_Spawn: Couldn't Create('%s').\n",EntityName);
01908 return GE_FALSE;
01909 }
01910 Object = ips->physicsObjectListHeadPtr;
01911 Object2 = Object;
01912 while (Object)
01913 {
01914 if (gePhysicsSystem_AddObject(ips->physsysData, Object->stateInfo) == GE_FALSE)
01915 {
01916 GenVS_Error( "PhysicalSystem_Spawn: Couldn't AddObject('%s').\n",EntityName);
01917 return GE_FALSE;
01918 }
01919 Object = Object->Next;
01920 if (Object2)
01921 {
01922 Object2 = Object2->Next;
01923 if (Object2)
01924 {
01925 Object2=Object2->Next;
01926 if (Object2)
01927 {
01928 if (Object2==Object)
01929 {
01930 GenVS_Error("PhysicalSystem_Spawn: Detected circular linked list in Next field('%s')\n",EntityName);
01931 return GE_FALSE;
01932 }
01933 }
01934 }
01935 }
01936 }
01937
01938 PhysicsJoint = ips->jointListHeadPtr;
01939 while (PhysicsJoint)
01940 {
01941 if (PhysicsJoint->jointData == NULL)
01942 {
01943 GenVS_Error( "PhysicalSystem_Spawn: Null jointData ('%s').\n",EntityName);
01944 return GE_FALSE;
01945 }
01946
01947 if (gePhysicsSystem_AddJoint(ips->physsysData, PhysicsJoint->jointData) == GE_FALSE)
01948 {
01949 GenVS_Error( "PhysicalSystem_Spawn: Couldn't AddPhysicsJoint('%s').\n",EntityName);
01950 return GE_FALSE;
01951 }
01952 PhysicsJoint = PhysicsJoint->Next;
01953 }
01954
01955 return GE_TRUE;
01956 }
01957
01958
01959
01960 static void PhysicalSystem_Destroy(GenVSI *VSI, void *PlayerData, void *ClassData)
01961 {
01962 GPlayer *Player;
01963 PhysicalSystem *ips;
01964
01965 Player = (GPlayer*)PlayerData;
01966
01967 ips = (PhysicalSystem*)ClassData;
01968
01969 assert(ips);
01970
01971 assert(ips->physsysData);
01972
01973 gePhysicsSystem_Destroy(&ips->physsysData);
01974 }
01975
01976
01977
01978 static geBoolean PhysicalSystem_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data)
01979 {
01980 return GE_TRUE;
01981 }
01982
01983
01984
01985 static geBoolean PhysicalSystem_Control(GenVSI* VSI, void* PlayerData, float Time)
01986 {
01987 GPlayer* player;
01988 PhysicalSystem* psPtr;
01989
01990 player = (GPlayer*)PlayerData;
01991 psPtr = (PhysicalSystem*)player->ClassData;
01992
01993 if (!gePhysicsSystem_Iterate(psPtr->physsysData, Time))
01994 {
01995 GenVS_Error( "PhysicalSystem_Control: Iterate() failed.\n");
01996 return GE_FALSE;
01997 }
01998
01999 return GE_TRUE;
02000 }
02001
02003
02004
02005 static geBoolean ForceField_Spawn(GenVSI* VSI, void* PlayerData, void* Class, char *EntityName)
02006 {
02007 GPlayer* player;
02008 ForceField* ff;
02009
02010 player = (GPlayer*)PlayerData;
02011 if (player == NULL)
02012 {
02013 GenVS_Error( "ForceField_Spawn: player = NULL ('%s').\n",EntityName);
02014 return GE_FALSE;
02015 }
02016
02017 ff = (ForceField*)player->ClassData;
02018 if (ff == NULL)
02019 {
02020 GenVS_Error( "ForceField_Spawn: ff = NULL ('%s').\n",EntityName);
02021 return GE_FALSE;
02022 }
02023
02024 player->ViewFlags = VIEW_TYPE_LOCAL;
02025
02026 player->Blocked = NULL;
02027 player->Control = ForceField_Control;
02028 player->Trigger = ForceField_Trigger;
02029
02030 return GE_TRUE;
02031 }
02032
02033 static geBoolean ForceField_Trigger(GenVSI* VSI, void* PlayerData, void* TargetData, void* data)
02034 {
02035
02036 return GE_TRUE;
02037 }
02038
02039 static geBoolean ForceField_Control(GenVSI* VSI, void* PlayerData, float Time)
02040 {
02041 return GE_TRUE;
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058 void SqueezeVector(geVec3d *Vect, float Epsilon)
02059 {
02060 if (Vect->X > -Epsilon && Vect->X < Epsilon)
02061 Vect->X = 0.0f;
02062 if (Vect->Y > -Epsilon && Vect->Y < Epsilon)
02063 Vect->Y = 0.0f;
02064 if (Vect->Z > -Epsilon && Vect->Z < Epsilon)
02065 Vect->Z = 0.0f;
02066 }
02067
02068
02069
02070
02071 void ClampVector(geVec3d *Vect, float Epsilon)
02072 {
02073 if (Vect->X > Epsilon)
02074 Vect->X = Epsilon;
02075 if (Vect->Y > Epsilon)
02076 Vect->Y = Epsilon;
02077 if (Vect->Z > Epsilon)
02078 Vect->Z = Epsilon;
02079
02080 if (Vect->X < -Epsilon)
02081 Vect->X = -Epsilon;
02082 if (Vect->Y < -Epsilon)
02083 Vect->Y = -Epsilon;
02084 if (Vect->Z < -Epsilon)
02085 Vect->Z = -Epsilon;
02086 }
02087
02088
02089
02090
02091 void ReflectVelocity(geVec3d *In, geVec3d *Normal, geVec3d *Out, float Scale)
02092 {
02093 float Reflect;
02094
02095 Reflect = geVec3d_DotProduct(In, Normal) * Scale;
02096
02097 Out->X = In->X - Normal->X*Reflect;
02098 Out->Y = In->Y - Normal->Y*Reflect;
02099 Out->Z = In->Z - Normal->Z*Reflect;
02100
02101 SqueezeVector(Out, 0.1f);
02102 }
02103
02104
02105
02106
02107 static geBoolean IsKeyDown(int KeyCode)
02108 {
02109 if (GetAsyncKeyState(KeyCode) & 0x8000)
02110 return GE_TRUE;
02111
02112 return GE_FALSE;
02113 }
02114
02115
02116
02117
02118 BOOL XFormFromVector(const geVec3d *Source, const geVec3d *Target, float Roll, geXForm3d *Out)
02119 {
02120 geVec3d p1, p2, Vect;
02121 geVec3d Origin = {0.0f, 0.0f, 0.0f};
02122
02123 geVec3d_Subtract(Source, Target, &Vect);
02124
02125 if (geVec3d_Compare(&Vect, &Origin, 0.05f))
02126 {
02127 Vect.Y = -1.0f;
02128 }
02129
02130
02131 geXForm3d_SetIdentity(Out);
02132
02133 geVec3d_Normalize(&Vect);
02134
02135
02136 Out->AZ = Vect.X;
02137 Out->BZ = Vect.Y;
02138 Out->CZ = Vect.Z;
02139
02140
02141 p2.X = 0.0f;
02142 p2.Y = 1.0f;
02143 p2.Z = 0.0f;
02144
02145
02146 geVec3d_CrossProduct(&p2, &Vect, &p1);
02147 geVec3d_Normalize(&p1);
02148
02149
02150 Out->AX = p1.X;
02151 Out->BX = p1.Y;
02152 Out->CX = p1.Z;
02153
02154
02155 geVec3d_CrossProduct(&Vect, &p1, &p2);
02156 geVec3d_Normalize(&p2);
02157
02158
02159 Out->AY = p2.X;
02160 Out->BY = p2.Y;
02161 Out->CY = p2.Z;
02162
02163
02164 Out->Translation = *Source;
02165
02166 return TRUE;
02167 }
02168
02169
02170
02171
02172 void SetupPlayerXForm(GenVSI *VSI, void *PlayerData, float Time)
02173 {
02174 geVec3d Pos;
02175 GPlayer *Player;
02176 GenVSI_CMove *Move;
02177
02178 Player = (GPlayer*)PlayerData;
02179
02180 assert(Player->ClientHandle != CLIENT_NULL_HANDLE);
02181
02182 Move = GenVSI_GetClientMove(VSI, Player->ClientHandle);
02183
02184 assert(Move);
02185
02186 Pos = Player->XForm.Translation;
02187
02188
02189 geXForm3d_SetIdentity(&Player->XForm);
02190
02191
02192 geXForm3d_RotateZ(&Player->XForm, Move->Angles.Z+Player->Roll);
02193
02194 geXForm3d_RotateX(&Player->XForm, Move->Angles.X);
02195 geXForm3d_RotateY(&Player->XForm, Move->Angles.Y);
02196
02197 geXForm3d_Translate(&Player->XForm, Pos.X, Pos.Y, Pos.Z);
02198
02199 }
02200
02201
02202
02203
02204 geBoolean AnimatePlayer(GenVSI *VSI, void *PlayerData, uint16 MotionIndex, float Speed, geBoolean Loop)
02205 {
02206 float StartTime, EndTime, DeltaT;
02207 geBoolean Looped;
02208 GPlayer *Player;
02209
02210 Player = (GPlayer*)PlayerData;
02211
02212 Looped = GE_FALSE;
02213
02214 GenVSI_GetPlayerTimeExtents(VSI, Player, MotionIndex, &StartTime, &EndTime);
02215
02216 if (Speed > 0)
02217 {
02218 Player->FrameTime += Speed;
02219
02220 DeltaT = EndTime - StartTime;
02221
02222 if (Player->FrameTime >= EndTime)
02223 {
02224 if (Loop)
02225 Player->FrameTime -= DeltaT;
02226 else
02227 Player->FrameTime = EndTime;
02228 Looped = GE_TRUE;
02229 }
02230 }
02231 else if (Speed < 0)
02232 {
02233 Player->FrameTime += Speed;
02234
02235 DeltaT = EndTime - StartTime;
02236
02237 if (Player->FrameTime <= StartTime)
02238 {
02239 if (Loop)
02240 Player->FrameTime += DeltaT;
02241 else
02242 Player->FrameTime = StartTime;
02243 Looped = GE_TRUE;
02244 }
02245 }
02246
02247 return Looped;
02248 }
02249
02250
02251
02252
02253 geBoolean AnimatePlayer2(GenVSI *VSI, void *PlayerData, int32 MotionSlot, float Speed, geBoolean Loop)
02254 {
02255 float StartTime, EndTime, DeltaT;
02256 geBoolean Looped;
02257 GPlayer *Player;
02258 uint16 MotionIndex;
02259 float MotionTime;
02260
02261 Player = (GPlayer*)PlayerData;
02262
02263 assert(MotionSlot < Player->NumMotionData);
02264
02265 Looped = GE_FALSE;
02266
02267 MotionIndex = Player->MotionData[MotionSlot].MotionIndex;
02268 MotionTime = Player->MotionData[MotionSlot].MotionTime;
02269
02270 GenVSI_GetPlayerTimeExtents(VSI, Player, MotionIndex, &StartTime, &EndTime);
02271
02272 if (Speed > 0)
02273 {
02274 MotionTime += Speed;
02275
02276 DeltaT = EndTime - StartTime;
02277
02278 if (MotionTime >= EndTime)
02279 {
02280 if (Loop)
02281 MotionTime -= DeltaT;
02282 else
02283 MotionTime = EndTime;
02284 Looped = GE_TRUE;
02285 }
02286 }
02287 else if (Speed < 0)
02288 {
02289 MotionTime += Speed;
02290
02291 DeltaT = EndTime - StartTime;
02292
02293 if (MotionTime <= StartTime)
02294 {
02295 if (Loop)
02296 MotionTime += DeltaT;
02297 else
02298 MotionTime = StartTime;
02299 Looped = GE_TRUE;
02300 }
02301 }
02302
02303 Player->MotionData[MotionSlot].MotionTime = MotionTime;
02304
02305 return Looped;
02306 }
02307
02308
02309
02310
02311
02312 void UpdateClientInventory(GenVSI *VSI, GPlayer *Player, int32 Slot)
02313 {
02314 uint16 Amount;
02315 geBoolean Has;
02316
02317 assert(Player->Inventory[Player->CurrentWeapon] >= 0 && Player->Inventory[Player->CurrentWeapon] <= 65535);
02318
02319 Amount = (uint16)Player->Inventory[Slot];
02320 Has = Player->InventoryHas[Slot];
02321
02322 GenVSI_SetClientInventory(VSI, Player->ClientHandle, Slot, Amount, Has);
02323 }