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