1 #include "3dc.h"
2 #include "module.h"
3 #include "inline.h"
4
5 #include "stratdef.h"
6 #include "gamedef.h"
7 #include "dynblock.h"
8
9 #include "particle.h"
10 #include "sfx.h"
11 #include "detaillevels.h"
12 #include "bh_types.h"
13 #include "bh_ais.h"
14 #include "bh_pred.h"
15 #include "bh_corpse.h"
16 #include "lighting.h"
17 #define UseLocalAssert Yes
18 #include "ourasert.h"
19
20 static SFXBLOCK SfxBlockStorage[MAX_NO_OF_SFX_BLOCKS];
21 static int NumFreeSfxBlocks;
22 static SFXBLOCK *FreeSfxBlockList[MAX_NO_OF_SFX_BLOCKS];
23 static SFXBLOCK **FreeSfxBlockListPtr;
24
25
26
27 /*KJL***************************************************************************
28 * FUNCTIONS TO ALLOCATE AND DEALLOCATE SFX BLOCKS - KJL 12:02:14 11/13/96 *
29 ***************************************************************************KJL*/
InitialiseSfxBlocks(void)30 void InitialiseSfxBlocks(void)
31 {
32 SFXBLOCK *freeBlockPtr = SfxBlockStorage;
33 int blk;
34
35 for(blk=0; blk < MAX_NO_OF_SFX_BLOCKS; blk++)
36 {
37 FreeSfxBlockList[blk] = freeBlockPtr++;
38 }
39
40 FreeSfxBlockListPtr = &FreeSfxBlockList[MAX_NO_OF_SFX_BLOCKS-1];
41 NumFreeSfxBlocks = MAX_NO_OF_SFX_BLOCKS;
42 }
43
44
AllocateSfxBlock(void)45 SFXBLOCK* AllocateSfxBlock(void)
46 {
47 SFXBLOCK *sfxPtr = 0; /* Default to null ptr */
48
49 if (NumFreeSfxBlocks)
50 {
51 sfxPtr = *FreeSfxBlockListPtr--;
52 NumFreeSfxBlocks--;
53 }
54 else
55 {
56 /* unable to allocate a sfxamics block I'm afraid;
57 MAX_NO_OF_SFX_BLOCKS is too low */
58 //LOCALASSERT(NumFreeSfxBlocks);
59 textprint("No Free SFX blocks!\n");
60 }
61
62 return sfxPtr;
63 }
64
65
DeallocateSfxBlock(SFXBLOCK * sfxPtr)66 void DeallocateSfxBlock(SFXBLOCK *sfxPtr)
67 {
68 GLOBALASSERT(sfxPtr);
69 *(++FreeSfxBlockListPtr) = sfxPtr;
70 NumFreeSfxBlocks++;
71 }
72
73
74
CreateSFXObject(enum SFX_ID sfxID)75 DISPLAYBLOCK *CreateSFXObject(enum SFX_ID sfxID)
76 {
77 DISPLAYBLOCK *dispPtr = CreateActiveObject();
78
79 if (dispPtr)
80 {
81 SFXBLOCK *sfxPtr = AllocateSfxBlock();
82
83 if (sfxPtr)
84 {
85 dispPtr->SfxPtr = sfxPtr;
86 sfxPtr->SfxID = sfxID;
87 }
88 else
89 {
90 /* damn, we've got a DISPLAYBLOCK, but were unable to get a SFXBLOCK;
91 this means we must dealloc the DISPLAYBLOCK and return NULL to indicate
92 failure.
93 */
94 DestroyActiveObject(dispPtr);
95 dispPtr = 0;
96 }
97 }
98
99 return dispPtr;
100 }
101
102
DrawSfxObject(DISPLAYBLOCK * dispPtr)103 void DrawSfxObject(DISPLAYBLOCK *dispPtr)
104 {
105 SFXBLOCK *sfxPtr;
106
107 GLOBALASSERT(dispPtr);
108
109 sfxPtr = dispPtr->SfxPtr;
110 GLOBALASSERT(sfxPtr);
111
112
113 switch(sfxPtr->SfxID)
114 {
115 case SFX_MUZZLE_FLASH_AMORPHOUS:
116 {
117 if (!sfxPtr->EffectDrawnLastFrame)
118 {
119 VECTORCH direction;
120
121 direction.vx = dispPtr->ObMat.mat31;
122 direction.vy = dispPtr->ObMat.mat32;
123 direction.vz = dispPtr->ObMat.mat33;
124 DrawMuzzleFlash(&dispPtr->ObWorld,&direction,MUZZLE_FLASH_AMORPHOUS);
125 }
126 sfxPtr->EffectDrawnLastFrame=!sfxPtr->EffectDrawnLastFrame;
127
128 break;
129 }
130 case SFX_MUZZLE_FLASH_SMARTGUN:
131 {
132 VECTORCH direction;
133
134 direction.vx = dispPtr->ObMat.mat31;
135 direction.vy = dispPtr->ObMat.mat32;
136 direction.vz = dispPtr->ObMat.mat33;
137 DrawMuzzleFlash(&dispPtr->ObWorld,&direction,MUZZLE_FLASH_SMARTGUN);
138 break;
139 }
140 case SFX_MUZZLE_FLASH_SKEETER:
141 {
142 if (!sfxPtr->EffectDrawnLastFrame)
143 {
144 VECTORCH direction;
145
146 direction.vx = dispPtr->ObMat.mat31;
147 direction.vy = dispPtr->ObMat.mat32;
148 direction.vz = dispPtr->ObMat.mat33;
149 DrawMuzzleFlash(&dispPtr->ObWorld,&direction,MUZZLE_FLASH_SKEETER);
150 }
151 sfxPtr->EffectDrawnLastFrame=!sfxPtr->EffectDrawnLastFrame;
152
153 break;
154 }
155 case SFX_FRISBEE_PLASMA_BOLT:
156 {
157 VECTORCH direction;
158 direction.vx = dispPtr->ObMat.mat31;
159 direction.vy = dispPtr->ObMat.mat32;
160 direction.vz = dispPtr->ObMat.mat33;
161 DrawFrisbeePlasmaBolt(&dispPtr->ObWorld,&direction);
162
163 break;
164 }
165 case SFX_PREDATOR_PLASMA_BOLT:
166 {
167 VECTORCH direction;
168 direction.vx = dispPtr->ObMat.mat31;
169 direction.vy = dispPtr->ObMat.mat32;
170 direction.vz = dispPtr->ObMat.mat33;
171 DrawPredatorPlasmaBolt(&dispPtr->ObWorld,&direction);
172
173 break;
174 }
175 case SFX_SMALL_PREDATOR_PLASMA_BOLT:
176 {
177 VECTORCH direction;
178 direction.vx = dispPtr->ObMat.mat31;
179 direction.vy = dispPtr->ObMat.mat32;
180 direction.vz = dispPtr->ObMat.mat33;
181 DrawSmallPredatorPlasmaBolt(&dispPtr->ObWorld,&direction);
182
183 break;
184 }
185
186 default:
187 {
188 GLOBALASSERT(0);
189 break;
190 }
191 }
192 }
193
HandleSfxForObject(DISPLAYBLOCK * dispPtr)194 void HandleSfxForObject(DISPLAYBLOCK *dispPtr)
195 {
196 STRATEGYBLOCK *sbPtr = dispPtr->ObStrategyBlock;
197
198 if (dispPtr->SpecialFXFlags & SFXFLAG_ONFIRE)
199 {
200 HandleObjectOnFire(dispPtr);
201 }
202
203 if (sbPtr)
204 {
205 if(sbPtr->I_SBtype == I_BehaviourNetCorpse)
206 {
207 NETCORPSEDATABLOCK *corpseDataPtr = (NETCORPSEDATABLOCK *)sbPtr->SBdataptr;
208
209 if(!( (dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND)&&(dispPtr->ObFlags2 < ONE_FIXED) )
210 && corpseDataPtr->This_Death->Electrical && ((FastRandom()&255)==0))
211 {
212 VECTORCH velocity;
213 velocity.vx = (FastRandom()&2047)-1024;
214 velocity.vy = (FastRandom()&2047)-1024;
215 velocity.vz = (FastRandom()&2047)-1024;
216 MakeParticle(&dispPtr->ObWorld,&velocity,PARTICLE_SPARK);
217 velocity.vx = (FastRandom()&2047)-1024;
218 velocity.vy = (FastRandom()&2047)-1024;
219 velocity.vz = (FastRandom()&2047)-1024;
220 MakeParticle(&dispPtr->ObWorld,&velocity,PARTICLE_SPARK);
221 MakeLightElement(&dispPtr->ObWorld,LIGHTELEMENT_ELECTRICAL_SPARKS);
222
223 }
224 }
225
226 }
227 }
228
229
HandleObjectOnFire(DISPLAYBLOCK * dispPtr)230 void HandleObjectOnFire(DISPLAYBLOCK *dispPtr)
231 {
232 int objectIsDisappearing;
233 extern int NormalFrameTime;
234 int noRequired = 1;
235 int i;
236 VECTORCH velocity;
237
238 if (!dispPtr->ObShape) return;
239
240 if (dispPtr->ObShapeData->shaperadius<=LocalDetailLevels.AlienEnergyViewThreshold) return;
241
242 #if 1
243 {
244 DYNAMICSBLOCK *dynPtr;
245 STRATEGYBLOCK *sbPtr;
246
247 sbPtr = dispPtr->ObStrategyBlock;
248 LOCALASSERT(sbPtr);
249 dynPtr = sbPtr->DynPtr;
250 LOCALASSERT(sbPtr);
251
252
253 velocity.vx = DIV_FIXED((dynPtr->Position.vx-dynPtr->PrevPosition.vx)*3,NormalFrameTime*4);
254 velocity.vy = DIV_FIXED((dynPtr->Position.vy-dynPtr->PrevPosition.vy)*3,NormalFrameTime*4);
255 velocity.vz = DIV_FIXED((dynPtr->Position.vz-dynPtr->PrevPosition.vz)*3,NormalFrameTime*4);
256
257 if (dispPtr==sbPtr->SBdptr) noRequired = 5;
258
259 }
260 #else
261 velocity.vx = 0;
262 velocity.vy = 0;
263 velocity.vz = 0;
264 #endif
265
266 objectIsDisappearing = ( (dispPtr->SpecialFXFlags & SFXFLAG_MELTINGINTOGROUND) &&(dispPtr->ObFlags2 <= ONE_FIXED) ) ;
267
268 for (i=0; i<noRequired; i++)
269 {
270 VECTORCH position;
271 position.vx = dispPtr->ObWorld.vx+(FastRandom()&255)-128;
272 position.vy = dispPtr->ObWorld.vy+(FastRandom()&255)-128;
273 position.vz = dispPtr->ObWorld.vz+(FastRandom()&255)-128;
274 #if 0
275 MakeParticle(&(position), &velocity, PARTICLE_NONCOLLIDINGFLAME);
276 #else
277 if (objectIsDisappearing)
278 {
279 if ((FastRandom()&65535) < dispPtr->ObFlags2)
280 MakeParticle(&(position), &velocity, PARTICLE_FIRE);
281 }
282 else
283 {
284 MakeParticle(&(position), &velocity, PARTICLE_FIRE);
285 }
286
287 if ((FastRandom()&65535) > 32768)
288 {
289 MakeParticle(&(position), &velocity, PARTICLE_IMPACTSMOKE);
290 }
291 #endif
292 }
293
294 }
295