Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

GMain.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  GMain.c                                                                             */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description:                                                                        */
00006 /*                                                                                      */
00007 /*  Copyright (c) 1997, 1999, Eclipse Entertainment; All rights reserved.               */
00008 /*                                                                                      */
00009 /*  See the accompanying file LICENSE.TXT for terms on the use of this library.         */
00010 /*  This library is distributed in the hope that it will be useful but WITHOUT          */
00011 /*  ANY WARRANTY OF ANY KIND and without any implied warranty of MERCHANTABILITY        */
00012 /*  or FITNESS FOR ANY PURPOSE.  Refer to LICENSE.TXT for more details.                 */
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, ...);  //oh, dear.
00026 
00027 //#define FLY_MODE
00028 
00029 // FIXME:  Take out Genesis.h dependency.  Replace with server API code that sits on top
00030 //                 of Genesis calls...
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 //      Server_Main
00071 //      Game code called, when server level starts up...
00072 //=====================================================================================
00073 geBoolean Server_Main(GenVSI *VSI, const char *LevelName)
00074 {
00075         Bot_Main(VSI, LevelName);
00076     
00077         CurrentPlayerStart = NULL;
00078 
00079         // SetClassSpawn functions get called once, and are used for each SetWorld...
00080         // Set the calss spawns
00081         GenVSI_SetClassSpawn(VSI, "DeathMatchStart", Player_Spawn, NULL);
00082         
00083         // Doors/Plats/PhysicalObjects/PhysicsJoints/PhysicalSystems/etc.
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         // Change level trigger
00094         GenVSI_SetClassSpawn(VSI, "ChangeLevel", ChangeLevel_Spawn, NULL);
00095 
00096         // Items
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         // Set the level with these spawns...
00109         // FIXME:  Rename to: Server_ExecuteClassSpawns(Server, LevelName);???????
00110         GenVSI_SetWorld(VSI, SetupWorldCB, ShutdownWorldCB, LevelName);         // Use the level name supplied by the host
00111 
00112         // Proc indexes
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 //      Client_Main
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 // Returns GE_FALSE if colliding with self, or owner to self...
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                 // NOTE  - Owner CAN be NULL...
00162                 if (GenVSI_ActorToPlayer(Data->VSI, Actor) == Data->Player->Owner)
00163                         return GE_FALSE;
00164         }
00165 
00166         return GE_TRUE;
00167 }
00168 
00169 // Returns GE_FALSE if colliding with self...
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 //      GetDMSpawn
00193 //=====================================================================================
00194 GPlayer *GetDMSpawn(GenVSI *VSI)
00195 {
00196         //if (GenVSI_GetMode(VSI) == 0)
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                 //if (!CurrentPlayerStart)
00205                 //      GenVS_Error( "Game_SpawnClient:  No PlayerStart!\n");
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 //      Game_SpawnClient
00229 //=====================================================================================
00230 geBoolean Game_SpawnClient(GenVSI *VSI, geWorld *World, void *PlayerData, void *ClassData)
00231 {
00232         int32                   i;
00233         GPlayer                 *Player;
00234 
00235         //Player = (GPlayer*)GenVSI_GetPlayerData(VSI, PlayerHandle);
00236         Player = (GPlayer*)PlayerData;
00237 
00238         geXForm3d_SetIdentity(&Player->XForm);
00239 
00240         // Get a DM start
00241 #ifndef FLY_MODE
00242         {
00243                 GPlayer                 *DMStart;
00244 
00245                 DMStart = GetDMSpawn(VSI);
00246                 Player->XForm = DMStart->XForm;
00247         }
00248 
00249         //GenVSI_SetPlayerBox(VSI, PlayerHandle, &Mins, &Maxs);
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         //GenVSI_SetClientGunOffset(VSI, ClientHandle, 0.0f, 130.0f, 0.0f);
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         // Set the view info
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         // Hook player up to client physics controller
00282         Player->ControlIndex = 0;
00283         Player->Control = Client_Control;
00284 
00285         // Set the view player on this machine to the clients player
00286         GenVSI_SetViewPlayer(VSI, Player->ClientHandle, Player);
00287 
00288         // Players keep track of scoring, health, etc for now.
00289         // Server_SetClientScore/Health must be called to update a particular client
00290         // that is associated with a player...
00291 
00292         Player->Health = 100;
00293         Player->Score = 0;
00294 
00295         // FIXME:  Soon, Scores, Health, etc won't be so arbitrary.  Maybe somthing like
00296         // Quake2's Layouts will be used instead, making it easier to make games that don't
00297         // use this sort of scoring system...
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 //      Game_DestroyClient
00320 //=====================================================================================
00321 void Game_DestroyClient(GenVSI *VSI, void *PlayerData, void *ClassData)
00322 {
00323         //GenVS_Error( "Client destroyed...");          // For debugging...
00324 }
00325 
00326 //=====================================================================================
00327 //      Local static functions...
00328 //=====================================================================================
00329 
00330 //extern geEngine *Engine;
00331 
00332 //=====================================================================================
00333 //      PlayerLiquid
00334 //
00335 //      Checks to see if the player is in a liquid state, and returns the power of the state
00336 //      Stronger numbers mean thicker liquid, etc...
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 //      CheckPlayer
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                         //geEngine_Printf(Engine, 10, 85, "Stuck");
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 //      MovePlayerUpStep
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         // Try to "pop" up on the step
00413         if (geWorld_Collision(World, &Mins, &Maxs, &Pos1, &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS, 0, NULL, NULL, &Collision2))
00414                 return GE_FALSE;        // Can't move
00415 
00416         // Move forward (opposite the normal)
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;        // Can't move
00422 
00423         // Put him back on the ground
00424         Pos1 = Pos2;
00425         Pos2.Y -= (STEP_HEIGHT+1.0f);
00426 
00427         // NOTE that this should allways return a collision
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 //      CheckVelocity
00444 //      Adjust players Velocity. based on what it's doing in the world
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         // end VAR section
00471         // BEGIN
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         // check for penetration of Player's bounding box into the radius of a ForceField entity
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                         // player is inside radius of force field, figure out how much force
00545                         // to apply based on force field's falloff function
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                 } // while
00569         } // if
00570         #endif
00571 
00572 
00573         for (HitCount=0 ; HitCount<NumHits ; HitCount++)
00574         {
00575                 float   Fd, Bd;
00576                 //Server_Player *UPlayer;
00577 
00578                 Pos = Player->XForm.Translation;
00579                 geVec3d_AddScaled(&Pos, &Player->Velocity, TimeLeft, &NewPos);
00580 
00581                 // Make sure the pos did not start out in solid
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;         // Covered the entire distance...
00600 
00601                 if (Collision.Plane.Normal.Y > 0.7f)
00602                 {
00603                         if (Player->State == PSTATE_InAir)
00604                                 Player->State = PSTATE_Normal;                  // Put the player on the ground if in air
00605                         else if (Player->State == PSTATE_Dead)
00606                                 Player->State = PSTATE_DeadOnGround;    // Put the player on the ground if in air
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)            // Just stop at actors for now...
00627                 {
00628                         geVec3d_Copy(&Player->LastGoodPos, &Player->XForm.Translation);
00629                         geVec3d_Clear(&Player->Velocity);
00630                         return GE_TRUE;
00631                 }
00632 
00633                 // FIXME:  Save this ratio in the impact function...
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)    // Actually covered some distance
00640                 {       
00641                         // Set the players pos to the impact point
00642                         geVec3d_Copy(&Collision.Impact, &Player->XForm.Translation);
00643                         // Restore Velocity
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                 //TimeLeft -= TimeLeft * Collision.Ratio;
00657                 
00658                 // Clipped to another plane
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                 // Add the plane hit, to the plane list
00667                 geVec3d_Copy (&Collision.Plane.Normal, &Planes[NumPlanes]);
00668                 NumPlanes++;
00669 
00670                 //
00671                 // Modify original_velocity so it parallels all of the clip planes
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;  // not ok
00683                                 }
00684                         }
00685                         if (j == NumPlanes)
00686                                 break;
00687                 }
00688                 
00689                 if (i != NumPlanes)
00690                 {       // Go along this plane
00691                         geVec3d_Copy(&NewVelocity, &Player->Velocity);
00692                 }
00693                 else
00694                 {       
00695                         if (NumPlanes != 2)
00696                         {
00697                                 //Console_Printf(Server->Host->Console, "Clip velocity, numplanes == %i\n",NumPlanes);
00698                                 geVec3d_Clear(&Player->Velocity);
00699                                 return GE_TRUE;
00700                         }
00701                         
00702                         //Console_Printf(Server->Host->Console, "Cross product\n",NumPlanes);
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                 //      Don't allow new velocity to go against original velocity unless told otherwise
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 //      PlayerPhysics
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         // Add gravity
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         // Apply friction
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                 // Apply movement friction
00787                 geVec3d_Scale(&Player->Velocity, NewSpeed, &Player->Velocity);
00788         }
00789         
00790         UpdatePlayerContents(VSI, Player, Time);
00791 
00792         return GE_TRUE;
00793 }
00794 
00795 //=====================================================================================
00796 //      UpdatePlayerContents
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                 // Check to see if player is in lava...
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 //      Client_Control
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         // FIXME:  Make this function take care of dead players also.  Use a switch statement or somthing.
00870         // We should not be changing control functions on the fly like that.  Could confuse the server/client...
00871         //assert(Player->State != PSTATE_Dead && Player->State != PSTATE_DeadOnGround);
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         // Make sure the xform is valid
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);               // Use the real in vector for liquid
00901         #else
00902                 if (PlayerLiquid(Player))
00903                         geXForm3d_GetIn(&Player->XForm, &InVect);               // Use the real in vector for liquid
00904                 else
00905                         geXForm3d_GetIn(&XForm, &InVect);
00906         #endif
00907 
00908         //if (VSI->Mode == MODE_Server)
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); // Force a weapon  update
00928         }
00929 
00930         MoveSpeed = Time;
00931 
00932         if (Player->State != PSTATE_Normal)
00933                 MoveSpeed *= 0.15f;
00934 
00935         // Set his movement Velocity
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         // Run polayer physics code...
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)           // Only do this stuff when we are in server mode...
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                 // Get a box a little bigger than the player for doors, etc...
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                 //if (geWorld_GetContents(World, &Player->XForm.Translation, &CMins, &CMaxs, GE_COLLIDE_ACTORS, 0xffffffff, NULL, NULL, &Contents))
01017                 {
01018                         if (Contents.Actor)
01019                         {
01020                                 GPlayer *TPlayer;
01021                                 static  int32   HackV;
01022 
01023                                 //GenVSI_ConsoleHeaderPrintf(VSI, Player->ClientHandle, GE_FALSE, "Hit actor:%i", HackV++);
01024 
01025                                 TPlayer = (GPlayer*)GenVSI_ActorToPlayer(VSI, Contents.Actor);
01026 
01027                                 if (TPlayer && TPlayer->Trigger)// && TPlayer->ViewFlags & VIEW_TYPE_TOUCH)
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         // Make sure the xform is valid
01081         SetupPlayerXForm(VSI, Player, Time);
01082 
01083         Player->VPos = Player->XForm.Translation;
01084 
01085         return GE_TRUE;
01086 }
01087 
01088 //=====================================================================================
01089 //      Player_Spawn
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 //      Door_Control
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)         // Played through, done...
01156         {
01157                 NewTime = StartTime;
01158                 Player->State = PSTATE_Closed;
01159 
01160                 Player->ViewFlags &= ~VIEW_TYPE_MODEL_OPEN;
01161         }
01162 
01163         // Get the xform for the current time
01164         gePath_Sample(Path, NewTime, &DestXForm);
01165 
01166         // If the player can move, then update time, and xform
01167         if (GenVSI_MovePlayerModel(VSI, Player, &DestXForm))
01168         {
01169                 Player->XForm = DestXForm;
01170                 //DData->AnimTime = NewTime;
01171                 Player->FrameTime = NewTime;
01172         }
01173 
01174         //geWorld_GetModelRotationalCenter(World, Model, &Player->VPos);
01175         //geVec3d_Add(&Player->VPos, &Player->XForm.Translation, &Player->VPos);
01176 
01177         return GE_TRUE;
01178 }
01179 
01180 //=====================================================================================
01181 //      Plat_Control
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)         // Played through, done...
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                 if (Plat->Loop)
01228                 {
01229                         Player->Trigger(VSI, Player, NULL);
01230                 }
01231                 */
01232         }
01233 
01234         // Get the xform for the current time
01235         gePath_Sample(Path, NewTime, &DestXForm);
01236 
01237         // If the player can move, then update time, and xform
01238         if (GenVSI_MovePlayerModel(VSI, Player, &DestXForm))
01239         {
01240                 Player->XForm = DestXForm;
01241                 //DData->AnimTime = NewTime;
01242                 Player->FrameTime = NewTime;
01243         }
01244 
01245         //geWorld_GetModelRotationalCenter(World, Model, &Player->VPos);
01246         //geVec3d_Add(&Player->VPos, &Player->XForm.Translation, &Player->VPos);
01247 
01248         return GE_TRUE;
01249 }
01250 
01251 //=====================================================================================
01252 //      Door_Trigger
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 //      Door_Blocked
01278 //=====================================================================================
01279 static geBoolean Door_Blocked(GenVSI *VSI, void *PlayerData, void *TargetData)
01280 {
01281         return GE_TRUE;
01282 }
01283 
01284 //=====================================================================================
01285 //      Door_Spawn
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         //Player->TriggerIndex = 2;
01304 
01305         Player->Time = 0.0f;
01306 
01307         // Setup the doors local user data (not passed accross network)
01308         // Grab the model
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         //geWorld_GetModelRotationalCenter(World, Model, &Player->VPos);
01323 
01324         // Set the default xform to time 0 of the animation
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         // Put model at default position
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);                // Special index
01346 
01347         // Register the model with the player if all is ok
01348         // NOTE - If somthing went bad, then this should not be called!!!
01349         GenVSI_RegisterPlayerModel(VSI, Player, Model);
01350         
01351         return GE_TRUE;
01352 }
01353 //=====================================================================================
01354 //      Plat_Trigger
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 //      Plat_Spawn
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         //Player->TriggerIndex = 4;
01412 
01413         // Setup the plats local user data (not passed accross network)
01414         Plat = (MovingPlat*)ClassData;
01415 
01416         Player->VPos = Plat->Origin;
01417 
01418         // Grab the model
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         //geWorld_GetModelRotationalCenter(World, Model, &Player->VPos);
01430 
01431         // Set the default xform to time 0 of the animation
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         // Put model at default position
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);                // Special index
01453 
01454         // Register the model with the player if all is ok
01455         // NOTE - If somthing went bad, then this should not be called!!!
01456         GenVSI_RegisterPlayerModel(VSI, Player, Model);
01457         /*
01458         if (Plat->Loop)
01459         {
01460                 Player->Trigger(VSI, Player, NULL);
01461         }
01462         */
01463         return GE_TRUE;
01464 }
01465 
01468 
01469 //=====================================================================================
01470 //      PhysicsObject_Spawn
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                                                                                                                                 //po->physicsScale);
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         // Register the model with the player if all is ok
01560         // NOTE - If somthing went bad, then this should not be called!!!
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         // PlayerData actually points to the PhysicsObject.
01585         // Target is R. Havoc.
01586         // Makes sense, doesn't it?                                     :^D
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         // check for penetration of one or more model vertices into the radius of a ForceField entity
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                                 // figure out how much force to apply based on force field's falloff function
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                         }       // for i        
01760                 } // while
01761         } // if
01762         #endif
01763 
01764         // update model's xform
01765         gePhysicsObject_GetXFormInEditorSpace(pod, &destXForm, activeConfigIndex);
01766         if (GenVSI_MovePlayerModel(VSI, player, &destXForm))
01767         {
01768                 //gePhysicsObject_GetXFormInEditorSpace(pod, &xform, activeConfigIndex);
01769                 geXForm3d_Copy(&destXForm, &player->XForm);
01770         }
01771 
01772         return GE_TRUE;
01773 }
01774 
01778 //=====================================================================================
01779 //      PhysicsJoint_Spawn
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                                                                                                                                  //ij->physicsScale);
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 //      PhysicalSystem_Spawn
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 // force field-related stuff
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 //      Spawn_AmbientSound
02047 //=====================================================================================
02048 static geBoolean Spawn_AmbientSound(Server_Server *Server, Server_Player *Player, void *ClassData)
02049 {
02050         Player->SoundIndex = SOUND_INDEX_WATERFALL;
02051 
02052 }
02053 */
02054 
02055 //=====================================================================================
02056 //      SqueezeVector
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 //      ClampVector
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 //      ReflectVelocity
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 //      IsKeyDown
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 //      XFormFromVector
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         // First clear the xform
02131         geXForm3d_SetIdentity(Out);
02132 
02133         geVec3d_Normalize(&Vect);
02134 
02135         // Now set the IN vector
02136         Out->AZ = Vect.X;
02137         Out->BZ = Vect.Y;
02138         Out->CZ = Vect.Z;
02139 
02140         // Get a straight up vector
02141         p2.X = 0.0f;
02142         p2.Y = 1.0f;
02143         p2.Z = 0.0f;
02144 
02145         // Use it with the in vector to get the RIGHT vector
02146         geVec3d_CrossProduct(&p2, &Vect, &p1);
02147         geVec3d_Normalize(&p1);
02148 
02149         // Put the RIGHT vector in the matrix
02150         Out->AX = p1.X;
02151         Out->BX = p1.Y;
02152         Out->CX = p1.Z;
02153 
02154         // Now use the RIGHT vector with the IN vector to get the real UP vector
02155         geVec3d_CrossProduct(&Vect, &p1, &p2);
02156         geVec3d_Normalize(&p2);
02157 
02158         // Put the UP vector in the matrix
02159         Out->AY = p2.X;
02160         Out->BY = p2.Y;
02161         Out->CY = p2.Z;
02162         
02163         // Put the translation in...
02164         Out->Translation = *Source;
02165 
02166         return TRUE;
02167 }
02168 
02169 //=====================================================================================
02170 //      SetupPlayerXForm
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         // Clear the matrix
02189         geXForm3d_SetIdentity(&Player->XForm);
02190 
02191         // Rotate then translate.
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 //      AnimatePlayer
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 //      AnimatePlayer
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 //      UpdateClientInventory
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 }

Generated on Tue Sep 30 12:35:52 2003 for GTestAndEngine by doxygen 1.3.2