1 #include "3dc.h"
2 #include "inline.h"
3 #include "module.h"
4 #include "stratdef.h"
5 #include "gamedef.h"
6 #include "bh_types.h"
7 #include "bh_videoscreen.h"
8 #include "dynblock.h"
9 #include "dynamics.h"
10 #include "bh_debri.h"
11 #include "plat_shp.h"
12
13 #define UseLocalAssert Yes
14 #include "ourasert.h"
15
16 #include "pvisible.h"
17
18
19
InitVideoScreen(void * bhdata,STRATEGYBLOCK * sbPtr)20 void* InitVideoScreen(void* bhdata,STRATEGYBLOCK *sbPtr)
21 {
22 TOOLS_DATA_VIDEO_SCREEN *toolsData = (TOOLS_DATA_VIDEO_SCREEN *)bhdata;
23 VIDEO_SCREEN_BEHAV_BLOCK* videoScreen;
24 int i;
25
26 LOCALASSERT(sbPtr->I_SBtype == I_BehaviourVideoScreen);
27 LOCALASSERT(toolsData);
28
29 /* create, initialise and attach a data block */
30 videoScreen = (void *)AllocateMem(sizeof(VIDEO_SCREEN_BEHAV_BLOCK));
31 if(!videoScreen)
32 {
33 memoryInitialisationFailure = 1;
34 return ((void *)NULL);
35 }
36 videoScreen->bhvr_type=I_BehaviourVideoScreen;
37
38 sbPtr->SBdataptr = videoScreen;
39
40
41 /* set default indestructibility */
42 videoScreen->Indestructable = No;
43
44
45 /* Initialise object's stats */
46 //set health and armour
47 {
48 NPC_DATA *NpcData;
49
50 NpcData=GetThisNpcData(I_NPC_DefaultInanimate);
51 LOCALASSERT(NpcData);
52 sbPtr->SBDamageBlock.Health=NpcData->StartingStats.Health<<ONE_FIXED_SHIFT;
53 sbPtr->SBDamageBlock.Armour=NpcData->StartingStats.Armour<<ONE_FIXED_SHIFT;
54 sbPtr->SBDamageBlock.SB_H_flags=NpcData->StartingStats.SB_H_flags;
55 }
56
57 sbPtr->SBDamageBlock.Health*=toolsData->integrity;
58
59 //get a dynamics block
60 sbPtr->DynPtr = AllocateDynamicsBlock(DYNAMICS_TEMPLATE_STATIC);
61
62 if(!sbPtr->DynPtr)
63 {
64 RemoveBehaviourStrategy(sbPtr);
65 return 0;
66 }
67
68
69 //is this screen indestructable
70 if (toolsData->integrity > 20)
71 {
72 videoScreen->Indestructable = Yes;
73 sbPtr->integrity = DEFAULT_OBJECT_INTEGRITY;
74 }
75 else if (toolsData->integrity < 1)
76 {
77 sbPtr->integrity = 1; // die immediately
78 }
79 else
80 {
81 sbPtr->integrity = (DEFAULT_OBJECT_INTEGRITY)*(toolsData->integrity);
82 }
83
84
85 /* Initialise the dynamics block */
86 {
87 DYNAMICSBLOCK *dynPtr = sbPtr->DynPtr;
88 GLOBALASSERT(dynPtr);
89
90 dynPtr->PrevPosition = dynPtr->Position = toolsData->position;
91 dynPtr->OrientEuler = toolsData->orientation;
92 CreateEulerMatrix(&dynPtr->OrientEuler, &dynPtr->OrientMat);
93 TransposeMatrixCH(&dynPtr->OrientMat);
94 }
95
96 /* strategy block initialisation */
97 sbPtr->shapeIndex = toolsData->shapeIndex;
98 for(i=0;i<SB_NAME_LENGTH;i++) sbPtr->SBname[i] = toolsData->nameID[i];
99
100
101 /*check to see if object is animated.*/
102 {
103 TXACTRLBLK **pptxactrlblk;
104 int item_num;
105 int shape_num = toolsData->shapeIndex;
106 SHAPEHEADER *shptr = GetShapeData(shape_num);
107 pptxactrlblk = &videoScreen->inan_tac;
108 for(item_num = 0; item_num < shptr->numitems; item_num ++)
109 {
110 POLYHEADER *poly = (POLYHEADER*)(shptr->items[item_num]);
111 LOCALASSERT(poly);
112
113 SetupPolygonFlagAccessForShape(shptr);
114
115 if((Request_PolyFlags((void *)poly)) & iflag_txanim)
116 {
117 TXACTRLBLK *pnew_txactrlblk;
118
119 pnew_txactrlblk = AllocateMem(sizeof(TXACTRLBLK));
120 if(pnew_txactrlblk)
121 {
122 pnew_txactrlblk->tac_flags = 0;
123 pnew_txactrlblk->tac_item = item_num;
124 pnew_txactrlblk->tac_sequence = 0;
125 pnew_txactrlblk->tac_node = 0;
126 pnew_txactrlblk->tac_txarray = GetTxAnimArrayZ(shape_num, item_num);
127 pnew_txactrlblk->tac_txah_s = GetTxAnimHeaderFromShape(pnew_txactrlblk, shape_num);
128
129 *pptxactrlblk = pnew_txactrlblk;
130 pptxactrlblk = &pnew_txactrlblk->tac_next;
131 }
132 else *pptxactrlblk = NULL;
133 }
134 }
135 *pptxactrlblk=0;
136
137 }
138
139 //copy destruction target stuff
140 videoScreen->destruct_target_request=toolsData->destruct_target_request;
141 for(i=0;i<SB_NAME_LENGTH;i++)
142 {
143 videoScreen->destruct_target_ID[i]=toolsData->destruct_target_ID[i];
144 }
145 videoScreen->destruct_target_sbptr=0;
146
147 return((void*)videoScreen);
148
149 }
150
151
152
153
VideoScreenBehaviour(STRATEGYBLOCK * sbPtr)154 void VideoScreenBehaviour(STRATEGYBLOCK *sbPtr)
155 {
156 DISPLAYBLOCK* dptr;
157 VIDEO_SCREEN_BEHAV_BLOCK* videoScreen;
158 GLOBALASSERT(sbPtr);
159 videoScreen = sbPtr->SBdataptr;
160 GLOBALASSERT(videoScreen);
161
162 dptr = sbPtr->SBdptr;
163 if(dptr)
164 {
165 LIGHTBLOCK *lightPtr = dptr->ObLights[0];
166 //update light if near
167 if (lightPtr)
168 {
169 if(sbPtr->SBdptr->ObNumLights==1)
170 {
171 extern int FmvColourRed;
172 extern int FmvColourGreen;
173 extern int FmvColourBlue;
174
175 lightPtr->LightBright = ONE_FIXED;
176 lightPtr->LightFlags = LFlag_Omni;
177 lightPtr->LightType = LightType_PerVertex;
178 lightPtr->LightRange = 5000;
179
180 lightPtr->RedScale= FmvColourRed;
181 lightPtr->GreenScale= FmvColourGreen;
182 lightPtr->BlueScale= FmvColourBlue;
183 }
184 }
185
186 //deal with texture animation if near
187 if(videoScreen->inan_tac)
188 {
189 if(!dptr->ObTxAnimCtrlBlks)
190 {
191 dptr->ObTxAnimCtrlBlks = videoScreen->inan_tac;
192 }
193 }
194 }
195 }
196
197
198
199
VideoScreenIsDamaged(STRATEGYBLOCK * sbPtr,DAMAGE_PROFILE * damage,int multiple)200 void VideoScreenIsDamaged(STRATEGYBLOCK *sbPtr, DAMAGE_PROFILE *damage, int multiple)
201 {
202 VIDEO_SCREEN_BEHAV_BLOCK* videoScreen;
203 GLOBALASSERT(sbPtr);
204 videoScreen = sbPtr->SBdataptr;
205 GLOBALASSERT(videoScreen);
206
207 //no netweok code for this yet (if ever)
208 if (!videoScreen->Indestructable)
209 {
210 if(sbPtr->SBDamageBlock.Health <= 0)
211 {
212 //notify target of destruction
213 if(videoScreen->destruct_target_sbptr)
214 {
215 RequestState(videoScreen->destruct_target_sbptr,videoScreen->destruct_target_request,0);
216 }
217
218
219 //the object has been destroyed
220 MakeFragments(sbPtr);
221 DestroyAnyStrategyBlock(sbPtr);
222 }
223 }
224 }
225
226
227
228 /*--------------------**
229 ** Loading and Saving **
230 **--------------------*/
231 #include "savegame.h"
232
233 typedef struct video_screen_save_block
234 {
235 SAVE_BLOCK_STRATEGY_HEADER header;
236
237 BOOL Indestructable;
238
239
240 //strategyblock stuff
241 int integrity;
242 DAMAGEBLOCK SBDamageBlock;
243 }VIDEO_SCREEN_SAVE_BLOCK;
244
245
246
LoadStrategy_VideoScreen(SAVE_BLOCK_STRATEGY_HEADER * header)247 void LoadStrategy_VideoScreen(SAVE_BLOCK_STRATEGY_HEADER* header)
248 {
249 STRATEGYBLOCK* sbPtr;
250 VIDEO_SCREEN_BEHAV_BLOCK* videoScreen;
251 VIDEO_SCREEN_SAVE_BLOCK* block = (VIDEO_SCREEN_SAVE_BLOCK*) header;
252
253 //check the size of the save block
254 if(header->size!=sizeof(*block)) return;
255
256 //find the existing strategy block
257 sbPtr = FindSBWithName(header->SBname);
258 if(!sbPtr) return;
259
260 //make sure the strategy found is of the right type
261 if(sbPtr->I_SBtype != I_BehaviourVideoScreen) return;
262
263 videoScreen = (VIDEO_SCREEN_BEHAV_BLOCK*)sbPtr->SBdataptr;
264
265 //start copying stuff
266
267 videoScreen->Indestructable = block->Indestructable;
268
269 sbPtr->integrity = block->integrity;
270 sbPtr->SBDamageBlock = block->SBDamageBlock;
271 }
272
273
SaveStrategy_VideoScreen(STRATEGYBLOCK * sbPtr)274 void SaveStrategy_VideoScreen(STRATEGYBLOCK* sbPtr)
275 {
276 VIDEO_SCREEN_SAVE_BLOCK *block;
277 VIDEO_SCREEN_BEHAV_BLOCK* videoScreen;
278
279 videoScreen = (VIDEO_SCREEN_BEHAV_BLOCK*)sbPtr->SBdataptr;
280
281 GET_STRATEGY_SAVE_BLOCK(block,sbPtr);
282
283 //start copying stuff
284 block->Indestructable = videoScreen->Indestructable;
285
286 block->integrity = sbPtr->integrity;
287 block->SBDamageBlock = sbPtr->SBDamageBlock;
288
289 }
290