avp/3dc/avp/BonusAbilities.c
Rebellion Developments 218ca90543 Import Aliens vs Predator - Gold (Build 116)
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.
2019-08-19 05:45:17 +02:00

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;
}