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