1 /* CDF 9/10/98 A bold new initiaitive! */
2 
3 #include "3dc.h"
4 #include "inline.h"
5 #include "module.h"
6 
7 #include "stratdef.h"
8 #include "gamedef.h"
9 #include "bh_types.h"
10 
11 #include "dynblock.h"
12 #include "dynamics.h"
13 
14 #include "weapons.h"
15 #include "comp_shp.h"
16 #include "inventry.h"
17 #include "triggers.h"
18 
19 #define UseLocalAssert Yes
20 
21 #include "ourasert.h"
22 
23 #include "pmove.h"
24 #include "pvisible.h"
25 #include "bh_swdor.h"
26 #include "bh_plift.h"
27 #include "load_shp.h"
28 #include "bh_weap.h"
29 #include "bh_debri.h"
30 #include "lighting.h"
31 #include "bh_lnksw.h"
32 #include "bh_binsw.h"
33 #include "pheromon.h"
34 #include "bh_pred.h"
35 #include "bh_agun.h"
36 #include "plat_shp.h"
37 #include "psnd.h"
38 #include "ai_sight.h"
39 #include "sequnces.h"
40 #include "huddefs.h"
41 #include "showcmds.h"
42 #include "sfx.h"
43 #include "bh_marin.h"
44 #include "bh_dummy.h"
45 #include "bh_far.h"
46 #include "targeting.h"
47 #include "dxlog.h"
48 #include "los.h"
49 #include "psndplat.h"
50 #include "extents.h"
51 
52 /* for win95 net game support */
53 #include "pldghost.h"
54 #include "pldnet.h"
55 
56 extern int NormalFrameTime;
57 extern unsigned char Null_Name[8];
58 extern ACTIVESOUNDSAMPLE ActiveSounds[];
59 extern SECTION * GetNamedHierarchyFromLibrary(const char * rif_name, const char * hier_name);
60 void CreateDummy(VECTORCH *Position);
61 
62 /* Begin code! */
63 
CastDummy(void)64 void CastDummy(void) {
65 
66 	#define BOTRANGE 2000
67 
68 	VECTORCH position;
69 
70 	if (AvP.Network!=I_No_Network) {
71 		NewOnScreenMessage("NO DUMMYS IN MULTIPLAYER MODE");
72 		return;
73 	}
74 
75 	position=Player->ObStrategyBlock->DynPtr->Position;
76 	position.vx+=MUL_FIXED(Player->ObStrategyBlock->DynPtr->OrientMat.mat31,BOTRANGE);
77 	position.vy+=MUL_FIXED(Player->ObStrategyBlock->DynPtr->OrientMat.mat32,BOTRANGE);
78 	position.vz+=MUL_FIXED(Player->ObStrategyBlock->DynPtr->OrientMat.mat33,BOTRANGE);
79 
80 	CreateDummy(&position);
81 
82 }
83 
CreateDummy(VECTORCH * Position)84 void CreateDummy(VECTORCH *Position) {
85 
86 	STRATEGYBLOCK* sbPtr;
87 
88 	/* create and initialise a strategy block */
89 	sbPtr = CreateActiveStrategyBlock();
90 	if(!sbPtr) {
91 		NewOnScreenMessage("FAILED TO CREATE DUMMY: SB CREATION FAILURE");
92 		return; /* failure */
93 	}
94 	InitialiseSBValues(sbPtr);
95 
96 	sbPtr->I_SBtype = I_BehaviourDummy;
97 
98 	AssignNewSBName(sbPtr);
99 
100 	/* create, initialise and attach a dynamics block */
101 	sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_MARINE_PLAYER);
102 	if(sbPtr->DynPtr)
103 	{
104 		EULER zeroEuler = {0,0,0};
105 		DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
106 		GLOBALASSERT(dynPtr);
107       	dynPtr->PrevPosition = dynPtr->Position = *Position;
108 		dynPtr->OrientEuler = zeroEuler;
109 		CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
110 		TransposeMatrixCH(&dynPtr->OrientMat);
111 	}
112 	else
113 	{
114 		/* dynamics block allocation failed... */
115 		RemoveBehaviourStrategy(sbPtr);
116 		NewOnScreenMessage("FAILED TO CREATE DUMMY: DYNBLOCK CREATION FAILURE");
117 		return;
118 	}
119 
120 	sbPtr->shapeIndex = 0;
121 
122 	sbPtr->maintainVisibility = 1;
123 	sbPtr->containingModule = ModuleFromPosition(&(sbPtr->DynPtr->Position), (MODULE*)0);
124 
125 	/* Initialise dummy's stats */
126 	{
127 		sbPtr->SBDamageBlock.Health=30000<<ONE_FIXED_SHIFT;
128 		sbPtr->SBDamageBlock.Armour=30000<<ONE_FIXED_SHIFT;
129 		sbPtr->SBDamageBlock.SB_H_flags.AcidResistant=1;
130 		sbPtr->SBDamageBlock.SB_H_flags.FireResistant=1;
131 		sbPtr->SBDamageBlock.SB_H_flags.ElectricResistant=1;
132 		sbPtr->SBDamageBlock.SB_H_flags.PerfectArmour=1;
133 		sbPtr->SBDamageBlock.SB_H_flags.ElectricSensitive=0;
134 		sbPtr->SBDamageBlock.SB_H_flags.Combustability=0;
135 		sbPtr->SBDamageBlock.SB_H_flags.Indestructable=1;
136 	}
137 	/* create, initialise and attach a dummy data block */
138 	sbPtr->SBdataptr = (void *)AllocateMem(sizeof(DUMMY_STATUS_BLOCK));
139 	if(sbPtr->SBdataptr)
140 	{
141 		SECTION *root_section;
142 		DUMMY_STATUS_BLOCK *dummyStatus = (DUMMY_STATUS_BLOCK *)sbPtr->SBdataptr;
143 		GLOBALASSERT(dummyStatus);
144 
145 		dummyStatus->incidentFlag=0;
146 		dummyStatus->incidentTimer=0;
147 
148 		dummyStatus->HModelController.section_data=NULL;
149 		dummyStatus->HModelController.Deltas=NULL;
150 
151 		switch (AvP.PlayerType) {
152 			case I_Marine:
153 				dummyStatus->PlayerType=I_Marine;
154 				root_section=GetNamedHierarchyFromLibrary("hnpcmarine","marine with pulse rifle");
155 				if (!root_section) {
156 					RemoveBehaviourStrategy(sbPtr);
157 					NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL");
158 					return;
159 				}
160 				Create_HModel(&dummyStatus->HModelController,root_section);
161 				InitHModelSequence(&dummyStatus->HModelController,(int)HMSQT_MarineStand,(int)MSSS_Fidget_A,-1);
162 				break;
163 			case I_Alien:
164 				dummyStatus->PlayerType=I_Alien;
165 				root_section=GetNamedHierarchyFromLibrary("hnpcalien","alien");
166 				if (!root_section) {
167 					RemoveBehaviourStrategy(sbPtr);
168 					NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL");
169 					return;
170 				}
171 				Create_HModel(&dummyStatus->HModelController,root_section);
172 				InitHModelSequence(&dummyStatus->HModelController,(int)HMSQT_AlienStand,(int)ASSS_Standard,-1);
173 				break;
174 			case I_Predator:
175 				dummyStatus->PlayerType=I_Predator;
176 				root_section=GetNamedHierarchyFromLibrary("hnpcpredator","pred with wristblade");
177 				if (!root_section) {
178 					RemoveBehaviourStrategy(sbPtr);
179 					NewOnScreenMessage("FAILED TO CREATE DUMMY: NO HMODEL");
180 					return;
181 				}
182 				Create_HModel(&dummyStatus->HModelController,root_section);
183 				InitHModelSequence(&dummyStatus->HModelController,(int)HMSQT_PredatorStand,(int)PSSS_Standard,-1);
184 				break;
185 		}
186 		ProveHModel_Far(&dummyStatus->HModelController,sbPtr);
187 
188 		if(!(sbPtr->containingModule))
189 		{
190 			/* no containing module can be found... abort*/
191 			RemoveBehaviourStrategy(sbPtr);
192 			NewOnScreenMessage("FAILED TO CREATE DUMMY: MODULE CONTAINMENT FAILURE");
193 			return;
194 		}
195 		LOCALASSERT(sbPtr->containingModule);
196 
197 		MakeDummyNear(sbPtr);
198 
199 		NewOnScreenMessage("DUMMY CREATED");
200 
201 	} else {
202 		/* no data block can be allocated */
203 		RemoveBehaviourStrategy(sbPtr);
204 		NewOnScreenMessage("FAILED TO CREATE DUMMY: MALLOC FAILURE");
205 		return;
206 	}
207 }
208 
MakeDummyNear(STRATEGYBLOCK * sbPtr)209 void MakeDummyNear(STRATEGYBLOCK *sbPtr)
210 {
211 	extern MODULEMAPBLOCK AlienDefaultMap;
212 
213 	MODULE tempModule;
214 	DISPLAYBLOCK *dPtr;
215 	DYNAMICSBLOCK *dynPtr;
216 	DUMMY_STATUS_BLOCK *dummyStatusPointer;
217 
218 	LOCALASSERT(sbPtr);
219 	LOCALASSERT(sbPtr->SBdptr == NULL);
220 	dynPtr = sbPtr->DynPtr;
221 	dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbPtr->SBdataptr);
222     LOCALASSERT(dummyStatusPointer);
223     LOCALASSERT(dynPtr);
224 
225 
226 	AlienDefaultMap.MapShape = sbPtr->shapeIndex;
227 	tempModule.m_mapptr = &AlienDefaultMap;
228 	tempModule.m_sbptr = (STRATEGYBLOCK*)NULL;
229 	tempModule.m_numlights = 0;
230 	tempModule.m_lightarray = (struct lightblock *)0;
231 	tempModule.m_extraitemdata = (struct extraitemdata *)0;
232 	tempModule.m_dptr = NULL;
233 	AllocateModuleObject(&tempModule);
234 	dPtr = tempModule.m_dptr;
235 	if(dPtr==NULL) return; /* cannot allocate displayblock, so leave far */
236 
237 	sbPtr->SBdptr = dPtr;
238 	dPtr->ObStrategyBlock = sbPtr;
239 	dPtr->ObMyModule = NULL;
240 
241 	/* need to initialise positional information in the new display block */
242 	dPtr->ObWorld = dynPtr->Position;
243 	dPtr->ObEuler = dynPtr->OrientEuler;
244 	dPtr->ObMat = dynPtr->OrientMat;
245 
246 	/* zero linear velocity in dynamics block */
247 	sbPtr->DynPtr->LinVelocity.vx = 0;
248 	sbPtr->DynPtr->LinVelocity.vy = 0;
249 	sbPtr->DynPtr->LinVelocity.vz = 0;
250 
251 	/* state and sequence initialisation */
252 
253 	dPtr->HModelControlBlock=&dummyStatusPointer->HModelController;
254 
255 	ProveHModel(dPtr->HModelControlBlock,dPtr);
256 
257 	/*Copy extents from the collision extents in extents.c*/
258 	dPtr->ObMinX=-CollisionExtents[CE_MARINE].CollisionRadius;
259 	dPtr->ObMaxX=CollisionExtents[CE_MARINE].CollisionRadius;
260 	dPtr->ObMinZ=-CollisionExtents[CE_MARINE].CollisionRadius;
261 	dPtr->ObMaxZ=CollisionExtents[CE_MARINE].CollisionRadius;
262 	dPtr->ObMinY=CollisionExtents[CE_MARINE].CrouchingTop;
263 	dPtr->ObMaxY=CollisionExtents[CE_MARINE].Bottom;
264 	dPtr->ObRadius = 1000;
265 
266 }
267 
MakeDummyFar(STRATEGYBLOCK * sbPtr)268 void MakeDummyFar(STRATEGYBLOCK *sbPtr)
269 {
270 	DUMMY_STATUS_BLOCK *dummyStatusPointer;
271 	int i;
272 
273 	LOCALASSERT(sbPtr);
274 	LOCALASSERT(sbPtr->SBdptr != NULL);
275 	dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbPtr->SBdataptr);
276 	LOCALASSERT(dummyStatusPointer);
277 
278 	/* get rid of the displayblock */
279 	i = DestroyActiveObject(sbPtr->SBdptr);
280 	LOCALASSERT(i==0);
281 	sbPtr->SBdptr = NULL;
282 
283 	/* zero linear velocity in dynamics block */
284 	sbPtr->DynPtr->LinVelocity.vx = 0;
285 	sbPtr->DynPtr->LinVelocity.vy = 0;
286 	sbPtr->DynPtr->LinVelocity.vz = 0;
287 
288 }
289 
DummyBehaviour(STRATEGYBLOCK * sbPtr)290 void DummyBehaviour(STRATEGYBLOCK *sbPtr) {
291 
292 	DUMMY_STATUS_BLOCK *dummyStatusPointer;
293 
294 	LOCALASSERT(sbPtr);
295 	LOCALASSERT(sbPtr->containingModule);
296 	dummyStatusPointer = (DUMMY_STATUS_BLOCK *)(sbPtr->SBdataptr);
297     LOCALASSERT(dummyStatusPointer);
298 
299 	/* Should be the same near as far. */
300 	/* test if we've got a containing module: if we haven't, do nothing.
301 	This is important as the object could have been marked for deletion by the visibility
302 	management system...*/
303 	if(!sbPtr->containingModule)
304 	{
305 		DestroyAnyStrategyBlock(sbPtr); /* just to make sure */
306 		return;
307 	} else if (dummyStatusPointer->PlayerType!=I_Alien) {
308 		AddMarinePheromones(sbPtr->containingModule->m_aimodule);
309 	}
310 
311 	/* Incident handling. */
312 	dummyStatusPointer->incidentFlag=0;
313 
314 	dummyStatusPointer->incidentTimer-=NormalFrameTime;
315 
316 	if (dummyStatusPointer->incidentTimer<0) {
317 		dummyStatusPointer->incidentFlag=1;
318 		dummyStatusPointer->incidentTimer=32767+(FastRandom()&65535);
319 	}
320 
321 }
322