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