
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
448 lines
No EOL
11 KiB
C
448 lines
No EOL
11 KiB
C
/* KJL 16:14:35 09/09/98 - BonusAbilities.c */
|
|
#include "3dc.h"
|
|
#include "module.h"
|
|
#include "inline.h"
|
|
|
|
#include "stratdef.h"
|
|
#include "gamedef.h"
|
|
#include "bh_types.h"
|
|
|
|
#include "weapons.h"
|
|
#include "dynblock.h"
|
|
#include "avpview.h"
|
|
|
|
#include "load_shp.h"
|
|
#include "kzsort.h"
|
|
#include "kshape.h"
|
|
|
|
#include "pfarlocs.h"
|
|
#include "pvisible.h"
|
|
|
|
#define UseLocalAssert Yes
|
|
#include "ourasert.h"
|
|
|
|
|
|
extern int NormalFrameTime;
|
|
|
|
|
|
|
|
/* KJL 16:18:20 09/09/98 - Predator Grappling Hook */
|
|
struct GrapplingHookData
|
|
{
|
|
int IsEmbedded;
|
|
int IsEngaged;
|
|
int Tightness;
|
|
|
|
VECTORCH Position;
|
|
MATRIXCH Orientation;
|
|
int ShapeIndex;
|
|
DISPLAYBLOCK *DispPtr;
|
|
};
|
|
|
|
static struct GrapplingHookData GrapplingHook;
|
|
|
|
static DISPLAYBLOCK* CreateGrapplingHook(void);
|
|
|
|
|
|
extern void InitialiseGrapplingHook(void)
|
|
{
|
|
GrapplingHook.IsEngaged = 0;
|
|
GrapplingHook.IsEmbedded = 0;
|
|
GrapplingHook.ShapeIndex = GetLoadedShapeMSL("spear");
|
|
GrapplingHook.DispPtr = 0;
|
|
|
|
}
|
|
|
|
static void FireGrapplingHook(void);
|
|
void DisengageGrapplingHook(void);
|
|
|
|
extern void ActivateGrapplingHook(void)
|
|
{
|
|
if (GrapplingHook.IsEngaged)
|
|
{
|
|
DisengageGrapplingHook();
|
|
}
|
|
else
|
|
{
|
|
FireGrapplingHook();
|
|
}
|
|
}
|
|
static void FireGrapplingHook(void)
|
|
{
|
|
GrapplingHook.DispPtr = CreateGrapplingHook();
|
|
|
|
if (GrapplingHook.DispPtr)
|
|
{
|
|
GrapplingHook.IsEngaged = 1;
|
|
GrapplingHook.IsEmbedded = 0;
|
|
GrapplingHook.Tightness = ONE_FIXED;
|
|
|
|
/* CDF 14/4/99 Make a sound... */
|
|
Sound_Play(SID_GRAPPLE_THROW,"h");
|
|
|
|
#if 0
|
|
/* los */
|
|
GrapplingHook.Position = PlayersTarget.Position;
|
|
GrapplingHook.Orientation = Global_VDB_Ptr->VDB_Mat;
|
|
TransposeMatrixCH(&GrapplingHook.Orientation);
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
static DISPLAYBLOCK* CreateGrapplingHook(void)
|
|
{
|
|
STRATEGYBLOCK* sbPtr;
|
|
|
|
/* create and initialise a strategy block */
|
|
sbPtr = CreateActiveStrategyBlock();
|
|
if(!sbPtr) return NULL; /* failure */
|
|
InitialiseSBValues(sbPtr);
|
|
|
|
sbPtr->I_SBtype = I_BehaviourGrapplingHook;
|
|
|
|
AssignNewSBName(sbPtr);
|
|
|
|
/* create, initialise and attach a dynamics block */
|
|
sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_ROCKET);
|
|
if(sbPtr->DynPtr)
|
|
{
|
|
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
|
|
|
|
dynPtr->PrevPosition = dynPtr->Position = Global_VDB_Ptr->VDB_World;
|
|
|
|
GrapplingHook.Orientation = Global_VDB_Ptr->VDB_Mat;
|
|
TransposeMatrixCH(&GrapplingHook.Orientation);
|
|
dynPtr->OrientMat = GrapplingHook.Orientation;
|
|
|
|
dynPtr->LinVelocity.vx = dynPtr->OrientMat.mat31;
|
|
dynPtr->LinVelocity.vy = dynPtr->OrientMat.mat32;
|
|
dynPtr->LinVelocity.vz = dynPtr->OrientMat.mat33;
|
|
}
|
|
else
|
|
{
|
|
/* dynamics block allocation failed... */
|
|
RemoveBehaviourStrategy(sbPtr);
|
|
return NULL;
|
|
}
|
|
|
|
sbPtr->shapeIndex = GetLoadedShapeMSL("spear");
|
|
|
|
sbPtr->maintainVisibility = 0;
|
|
sbPtr->containingModule = ModuleFromPosition(&(sbPtr->DynPtr->Position), 0);
|
|
LOCALASSERT(sbPtr->containingModule);
|
|
if(!(sbPtr->containingModule))
|
|
{
|
|
/* no containing module can be found... abort*/
|
|
RemoveBehaviourStrategy(sbPtr);
|
|
return NULL;
|
|
}
|
|
{
|
|
MODULE tempModule;
|
|
DISPLAYBLOCK *dPtr;
|
|
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
|
|
|
|
VisibilityDefaultObjectMap.MapShape = sbPtr->shapeIndex;
|
|
tempModule.m_mapptr = &VisibilityDefaultObjectMap;
|
|
tempModule.m_sbptr = (STRATEGYBLOCK*)NULL;
|
|
tempModule.m_numlights = 0;
|
|
tempModule.m_lightarray = (struct lightblock *)0;
|
|
tempModule.m_extraitemdata = (struct extraitemdata *)0;
|
|
tempModule.m_dptr = NULL; /* this is important */
|
|
#if SupportWIndows95
|
|
tempModule.name = NULL; /* this is important */
|
|
#endif
|
|
AllocateModuleObject(&tempModule);
|
|
dPtr = tempModule.m_dptr;
|
|
if(dPtr==NULL)
|
|
{
|
|
RemoveBehaviourStrategy(sbPtr);
|
|
return NULL;
|
|
}
|
|
|
|
sbPtr->SBdptr = dPtr;
|
|
dPtr->ObStrategyBlock = sbPtr;
|
|
dPtr->ObMyModule = NULL;
|
|
dPtr->ObWorld = dynPtr->Position;
|
|
dPtr->ObEuler = dynPtr->OrientEuler;
|
|
dPtr->ObMat = dynPtr->OrientMat;
|
|
|
|
dPtr->ObRadius=10;
|
|
dPtr->ObMaxX=10;
|
|
dPtr->ObMinX=-10;
|
|
dPtr->ObMaxY=10;
|
|
dPtr->ObMinY=-10;
|
|
dPtr->ObMaxZ=10;
|
|
dPtr->ObMinZ=-10;
|
|
/* make displayblock a dynamic module object */
|
|
dPtr->ObFlags3 |= ObFlag3_DynamicModuleObject;
|
|
|
|
// sbPtr->SBDamageBlock.IsOnFire=1;
|
|
|
|
return dPtr;
|
|
}
|
|
|
|
}
|
|
|
|
extern void GrapplingHookBehaviour(STRATEGYBLOCK *sbPtr)
|
|
{
|
|
DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
|
|
|
|
if (!GrapplingHook.IsEmbedded)
|
|
{
|
|
COLLISIONREPORT *reportPtr = dynPtr->CollisionReportPtr;
|
|
|
|
if(reportPtr)
|
|
{
|
|
char stickWhereYouAre = 0;
|
|
|
|
if (reportPtr->ObstacleSBPtr)
|
|
{
|
|
DISPLAYBLOCK *dispPtr = reportPtr->ObstacleSBPtr->SBdptr;
|
|
if (dispPtr)
|
|
if (dispPtr->ObMyModule && (!dispPtr->ObMorphCtrl))
|
|
{
|
|
stickWhereYouAre=1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
stickWhereYouAre = 1;
|
|
}
|
|
|
|
|
|
if(stickWhereYouAre)
|
|
{
|
|
dynPtr->IsStatic=1;
|
|
dynPtr->PrevPosition=dynPtr->Position;
|
|
GrapplingHook.Position=dynPtr->Position;
|
|
GrapplingHook.IsEmbedded=1;
|
|
/* CDF 14/4/99 Make a sound. */
|
|
Sound_Play(SID_GRAPPLE_HIT_WALL,"d",&dynPtr->Position);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
DisengageGrapplingHook();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GrapplingHook.Tightness -= NormalFrameTime*4;
|
|
if (GrapplingHook.Tightness<0) GrapplingHook.Tightness=0;
|
|
}
|
|
}
|
|
|
|
extern void DisengageGrapplingHook(void)
|
|
{
|
|
GrapplingHook.IsEngaged = 0;
|
|
GrapplingHook.IsEmbedded = 0;
|
|
if (GrapplingHook.DispPtr)
|
|
{
|
|
RemoveBehaviourStrategy(GrapplingHook.DispPtr->ObStrategyBlock);
|
|
GrapplingHook.DispPtr=NULL;
|
|
}
|
|
}
|
|
|
|
extern void HandleGrapplingHookForces(void)
|
|
{
|
|
if (GrapplingHook.IsEmbedded)
|
|
{
|
|
DYNAMICSBLOCK *dynPtr = Player->ObStrategyBlock->DynPtr;
|
|
VECTORCH direction = GrapplingHook.Position;
|
|
int distance;
|
|
|
|
direction.vx -= dynPtr->Position.vx;
|
|
direction.vy -= dynPtr->Position.vy-1000;
|
|
direction.vz -= dynPtr->Position.vz;
|
|
|
|
distance = Approximate3dMagnitude(&direction);
|
|
if (distance>4096+1024)
|
|
{
|
|
Normalise(&direction);
|
|
dynPtr->LinImpulse.vx += MUL_FIXED(direction.vx,NormalFrameTime);
|
|
dynPtr->LinImpulse.vy += MUL_FIXED(direction.vy,NormalFrameTime);
|
|
dynPtr->LinImpulse.vz += MUL_FIXED(direction.vz,NormalFrameTime);
|
|
}
|
|
else if (distance>1024)
|
|
{
|
|
int s = MUL_FIXED((distance-1024)*16,NormalFrameTime);
|
|
Normalise(&direction);
|
|
dynPtr->LinImpulse.vx += MUL_FIXED(direction.vx,s);
|
|
dynPtr->LinImpulse.vy += MUL_FIXED(direction.vy,s);
|
|
dynPtr->LinImpulse.vz += MUL_FIXED(direction.vz,s);
|
|
|
|
dynPtr->LinImpulse.vx -= MUL_FIXED(dynPtr->LinImpulse.vx,NormalFrameTime/2);
|
|
dynPtr->LinImpulse.vy -= MUL_FIXED(dynPtr->LinImpulse.vy,NormalFrameTime/2);
|
|
dynPtr->LinImpulse.vz -= MUL_FIXED(dynPtr->LinImpulse.vz,NormalFrameTime/2);
|
|
}
|
|
|
|
if (Approximate3dMagnitude(&dynPtr->LinImpulse)>ONE_FIXED)
|
|
{
|
|
Normalise(&dynPtr->LinImpulse);
|
|
}
|
|
}
|
|
}
|
|
|
|
extern void RenderGrapplingHook(void)
|
|
{
|
|
if (GrapplingHook.IsEngaged && GrapplingHook.DispPtr)
|
|
{
|
|
extern void D3D_DrawCable(VECTORCH *centrePtr, MATRIXCH *orientationPtr);
|
|
extern int CloakingPhase;
|
|
VECTORCH cable[46];
|
|
int i;
|
|
{
|
|
MATRIXCH mat = Global_VDB_Ptr->VDB_Mat;
|
|
TransposeMatrixCH(&mat);
|
|
|
|
cable[0].vx = Global_VDB_Ptr->VDB_World.vx-mat.mat31/128;
|
|
cable[0].vy = Global_VDB_Ptr->VDB_World.vy-mat.mat32/128+500;
|
|
cable[0].vz = Global_VDB_Ptr->VDB_World.vz-mat.mat33/128;
|
|
}
|
|
// cable[0].vx = Global_VDB_Ptr->VDB_World.vx;
|
|
// cable[0].vy = Global_VDB_Ptr->VDB_World.vy+500;
|
|
// cable[0].vz = Global_VDB_Ptr->VDB_World.vz;
|
|
|
|
for (i=1; i<46; i++)
|
|
{
|
|
cable[i].vx = ((45-i)*cable[0].vx + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vx)/45;
|
|
cable[i].vy = ((45-i)*cable[0].vy + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vy)/45;
|
|
cable[i].vz = ((45-i)*cable[0].vz + (i)*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position.vz)/45;
|
|
|
|
if (GrapplingHook.Tightness!=0)
|
|
{
|
|
int x = GetSin((302*i+CloakingPhase)&4095)/256;
|
|
int y = GetSin((502*i+200+CloakingPhase)&4095)/256;
|
|
int z = GetCos((302*i+100+CloakingPhase)&4095)/256;
|
|
int u = GetSin( ((4096*i)/45)&4095 );
|
|
u = MUL_FIXED(MUL_FIXED(u,u),GrapplingHook.Tightness);
|
|
cable[i].vx += MUL_FIXED(u,x);
|
|
cable[i].vy += MUL_FIXED(u,y);
|
|
cable[i].vz += MUL_FIXED(u,z);
|
|
}
|
|
}
|
|
|
|
{
|
|
MATRIXCH mat;
|
|
VECTORCH dir = cable[45];
|
|
dir.vx -= cable[0].vx;
|
|
dir.vy -= cable[0].vy;
|
|
dir.vz -= cable[0].vz;
|
|
Normalise(&dir);
|
|
MakeMatrixFromDirection(&dir,&mat);
|
|
D3D_DrawCable(cable, &mat);
|
|
}
|
|
#if 0
|
|
DISPLAYBLOCK displayblock;
|
|
displayblock.ObWorld=GrapplingHook.Position;
|
|
displayblock.ObMat=GrapplingHook.Orientation;
|
|
displayblock.ObShape=GrapplingHook.ShapeIndex;
|
|
displayblock.ObShapeData=GetShapeData(GrapplingHook.ShapeIndex);
|
|
|
|
displayblock.name=NULL;
|
|
displayblock.ObEuler.EulerX=0;
|
|
displayblock.ObEuler.EulerY=0;
|
|
displayblock.ObEuler.EulerZ=0;
|
|
displayblock.ObFlags=0;
|
|
displayblock.ObFlags2=0;
|
|
displayblock.ObFlags3=0;
|
|
displayblock.ObNumLights=0;
|
|
displayblock.ObRadius=0;
|
|
displayblock.ObMaxX=0;
|
|
displayblock.ObMinX=0;
|
|
displayblock.ObMaxY=0;
|
|
displayblock.ObMinY=0;
|
|
displayblock.ObMaxZ=0;
|
|
displayblock.ObMinZ=0;
|
|
displayblock.ObTxAnimCtrlBlks=NULL;
|
|
displayblock.ObEIDPtr=NULL;
|
|
displayblock.ObMorphCtrl=NULL;
|
|
displayblock.ObStrategyBlock=NULL;
|
|
displayblock.ShapeAnimControlBlock=NULL;
|
|
displayblock.HModelControlBlock=NULL;
|
|
displayblock.ObMyModule=NULL;
|
|
displayblock.SpecialFXFlags = 0;
|
|
displayblock.SfxPtr=0;
|
|
|
|
MakeVector(&displayblock.ObWorld, &Global_VDB_Ptr->VDB_World, &displayblock.ObView);
|
|
RotateVector(&displayblock.ObView, &Global_VDB_Ptr->VDB_Mat);
|
|
RenderThisDisplayblock(&displayblock);
|
|
{
|
|
PARTICLE particle;
|
|
particle.Colour = 0xffffffff;
|
|
particle.ParticleID = PARTICLE_LASERBEAM;
|
|
particle.Position = Player->ObStrategyBlock->DynPtr->Position;
|
|
particle.Position.vy-=1000;
|
|
particle.Offset = GrapplingHook.DispPtr->ObStrategyBlock->DynPtr->Position;
|
|
particle.Size = 20;
|
|
RenderParticle(&particle);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*--------------------**
|
|
** Loading and Saving **
|
|
**--------------------*/
|
|
#include "savegame.h"
|
|
|
|
typedef struct grapple_save_block
|
|
{
|
|
SAVE_BLOCK_STRATEGY_HEADER header;
|
|
|
|
int IsEmbedded;
|
|
int IsEngaged;
|
|
int Tightness;
|
|
|
|
VECTORCH Position;
|
|
MATRIXCH Orientation;
|
|
//strategy block stuff
|
|
DYNAMICSBLOCK dynamics;
|
|
}GRAPPLE_SAVE_BLOCK;
|
|
|
|
//defines for load/save macros
|
|
#define SAVELOAD_BLOCK block
|
|
#define SAVELOAD_BEHAV (&GrapplingHook)
|
|
|
|
void LoadStrategy_Grapple(SAVE_BLOCK_STRATEGY_HEADER* header)
|
|
{
|
|
GRAPPLE_SAVE_BLOCK* block = (GRAPPLE_SAVE_BLOCK*) header;
|
|
|
|
//check the size of the save block
|
|
if(header->size!=sizeof(*block)) return;
|
|
|
|
//create the grappling hook
|
|
GrapplingHook.DispPtr = CreateGrapplingHook();
|
|
if(!GrapplingHook.DispPtr) return;
|
|
|
|
//copy suff from the save block
|
|
COPYELEMENT_LOAD(IsEmbedded)
|
|
COPYELEMENT_LOAD(IsEngaged)
|
|
COPYELEMENT_LOAD(Tightness)
|
|
COPYELEMENT_LOAD(Position)
|
|
COPYELEMENT_LOAD(Orientation)
|
|
|
|
*GrapplingHook.DispPtr->ObStrategyBlock->DynPtr = block->dynamics;
|
|
}
|
|
|
|
void SaveStrategy_Grapple(STRATEGYBLOCK* sbPtr)
|
|
{
|
|
GRAPPLE_SAVE_BLOCK* block;
|
|
|
|
GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
|
|
|
|
//copy stuff to the save block
|
|
COPYELEMENT_SAVE(IsEmbedded)
|
|
COPYELEMENT_SAVE(IsEngaged)
|
|
COPYELEMENT_SAVE(Tightness)
|
|
COPYELEMENT_SAVE(Position)
|
|
COPYELEMENT_SAVE(Orientation)
|
|
|
|
block->dynamics = *sbPtr->DynPtr;
|
|
block->dynamics.CollisionReportPtr=0;
|
|
} |